admin管理员组

文章数量:1323335

I have a Vue ponent in which I select a specific value from an array of objects then attempt to copy some fields from that value into Vue data

  <div class="container">
    <h4>Add Item</h4>
    <form @submit.prevent="addItem(item.Code)">
      <div class="row">
        <div class="col-md-6">
          <div class="form-group">
            <label for="ItemCode">Code</label>&nbsp;
            <select
              id="ItemCode"
              v-model="item.Code"
            >
              <input
                v-model="item.Code"
                type="hidden"
              >
              <option
                v-for="part in PartCodes"
                :key="part"
              >
                {{ part }}
              </option>
            </select>
   .
   .
   .
    </form>
  </div>

where the data is

  data() {
    return {
      item: {},
      parts: [],
    };
  },
  puted: {
    PartCodes: function () {
      return [...new Set(this.parts.map(p => p.Code))];
    },
  },
  created() {
    let uri = '/parts';
    if (process.env.NODE_ENV !== 'production') {
      uri = 'http://localhost:4000/parts';
    }
    this.axios.get(uri).then(response => {
      this.parts = response.data;
    });
  },
  methods: {
    addItem(selectCode) {
      let uri = '/items/create';
      if (process.env.NODE_ENV !== 'production') {
        uri = 'http://localhost:4000/items/create';
      }
      let selectPart = this.parts.filter( obj => {
        return obj.Code === selectCode;
      });

      this.item.Description = selectPart.Description;
      this.item.Cost = selectPart.Cost;
      this.item.Price = selectPart.Price);

      this.axios.post(uri, this.item)
        .then(() => {
          this.$router.push({name: 'QuoteIndex'});
        });
    }
  }
};

When I log the object 'selectPart' it has the correct fields but assigning these fields into the object 'items' results in 'undefined' values

I must be doing something wrong with scope but I don't know what is wrong.

Please suggest how I can copy fields with this Component

Thanks

I have a Vue ponent in which I select a specific value from an array of objects then attempt to copy some fields from that value into Vue data

  <div class="container">
    <h4>Add Item</h4>
    <form @submit.prevent="addItem(item.Code)">
      <div class="row">
        <div class="col-md-6">
          <div class="form-group">
            <label for="ItemCode">Code</label>&nbsp;
            <select
              id="ItemCode"
              v-model="item.Code"
            >
              <input
                v-model="item.Code"
                type="hidden"
              >
              <option
                v-for="part in PartCodes"
                :key="part"
              >
                {{ part }}
              </option>
            </select>
   .
   .
   .
    </form>
  </div>

where the data is

  data() {
    return {
      item: {},
      parts: [],
    };
  },
  puted: {
    PartCodes: function () {
      return [...new Set(this.parts.map(p => p.Code))];
    },
  },
  created() {
    let uri = '/parts';
    if (process.env.NODE_ENV !== 'production') {
      uri = 'http://localhost:4000/parts';
    }
    this.axios.get(uri).then(response => {
      this.parts = response.data;
    });
  },
  methods: {
    addItem(selectCode) {
      let uri = '/items/create';
      if (process.env.NODE_ENV !== 'production') {
        uri = 'http://localhost:4000/items/create';
      }
      let selectPart = this.parts.filter( obj => {
        return obj.Code === selectCode;
      });

      this.item.Description = selectPart.Description;
      this.item.Cost = selectPart.Cost;
      this.item.Price = selectPart.Price);

      this.axios.post(uri, this.item)
        .then(() => {
          this.$router.push({name: 'QuoteIndex'});
        });
    }
  }
};

When I log the object 'selectPart' it has the correct fields but assigning these fields into the object 'items' results in 'undefined' values

I must be doing something wrong with scope but I don't know what is wrong.

Please suggest how I can copy fields with this Component

Thanks

Share Improve this question edited Oct 11, 2019 at 5:05 Des Albert asked Oct 11, 2019 at 2:11 Des AlbertDes Albert 3312 gold badges5 silver badges20 bronze badges 9
  • If selectPart is the result of Array.prototype.filter(), won't it be an array? – Phil Commented Oct 11, 2019 at 3:36
  • No. console.log(selectPart) returns an object as expected – Des Albert Commented Oct 11, 2019 at 3:58
  • I'm not so sure about that and cannot see any console.log(selectPart). I say it's an array which is why selectPart.Description is undefined – Phil Commented Oct 11, 2019 at 4:08
  • I added the console.log(selectPart) while debugging Code: "CS-KVM-8P" Cost: 1688.37 Description: "INTEGRATED DIGITAL 8-PORT KVM OVER IP SWITCH" Price: 8410 _id: "5d9eb36a9814894c5cea8f83" looks like an object – Des Albert Commented Oct 11, 2019 at 4:19
  • 1 Thanks very much. Your suggestions solved my problem. Many thanks to Phil for helping to understand that 'selectPart' returned by 'filter()' is an array and to Daniel for explaining that the data fields should be declared pletely. The $set method also works as stated but it is simpler to just declare the data. – Des Albert Commented Oct 11, 2019 at 5:15
 |  Show 4 more ments

2 Answers 2

Reset to default 4

In Vue 2.x, properties added to objects are not reactive. You have declared the item data item without the properties Description and Price, and have later assigned these properties using simple object assignment, which Vue will not be able to track.

There are two ways to solve this:

1. Declare all reactive properties upfront

Change data to

data() {
    return {
      item: {
        Description: null,
        Price: null
      },
      parts: [],
    };
  },

2. Use Vue.set()

Change

this.item.Description = selectPart.Description;
this.item.Price = selectPart.Price;

to

this.$set(this.item, 'Description', selectPart.Description);
this.$set(this.item, 'Price', selectPart.Price);

Thankfully in Vue 3.x this caveat will be eliminated and all properties added to reactive objects will themselves bee reactive.

Here is a more elegant solution to the problem.

Replace .filter() with .find()

  <div class="container">
    <h4>Add Item</h4>
    <form @submit.prevent="addItem(item.Code)">
      <div class="row">
        <div class="col-md-6">
          <div class="form-group">
            <label for="ItemCode">Code</label>&nbsp;
            <select
              id="ItemCode"
              v-model="item.Code"
            >
              <input
                v-model="item.Code"
                type="hidden"
              >
              <option
                v-for="part in PartCodes"
                :key="part"
              >
                {{ part }}
              </option>
            </select>
   .
   .
   .
    </form>
  </div>

where the data is

  data() {
    return {
      item: {          
          Code: null,
          Description: null,
          Group: null,
          GroupCount: null,
          Quantity: null,
          ExtQuantity: null,
          Cost: null,
          Price: null,
          QuoteNumber: null},
      parts: [],
    };
  },
  puted: {
    PartCodes: function () {
      return [...new Set(this.parts.map(p => p.Code))];
    },
  },
  created() {
    let uri = '/parts';
    if (process.env.NODE_ENV !== 'production') {
      uri = 'http://localhost:4000/parts';
    }
    this.axios.get(uri).then(response => {
      this.parts = response.data;
    });
  },
  methods: {
    addItem(selectCode) {
      let uri = '/items/create';
      if (process.env.NODE_ENV !== 'production') {
        uri = 'http://localhost:4000/items/create';
      }
      let selectPart = this.parts.find( obj => {
        return obj.Code === selectCode;
      });

      this.item.Description = selectPart.Description;
      this.item.Cost = selectPart.Cost;
      this.item.Price = selectPar.Price;

      this.axios.post(uri, this.item)
        .then(() => {
          this.$router.push({name: 'QuoteIndex'});
        });
    }
  }
};

本文标签: javascriptObject assignment in Vuejs methodStack Overflow