【问题标题】:Object assignment in Vue.js methodVue.js 方法中的对象分配
【发布时间】:2019-10-11 02:11:42
【问题描述】:

我有一个 Vue 组件,我在其中从对象数组中选择一个特定值,然后尝试将该值中的一些字段复制到 Vue 数据中

  <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>

数据在哪里

  data() {
    return {
      item: {},
      parts: [],
    };
  },
  computed: {
    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'});
        });
    }
  }
};

当我记录对象“selectPart”时,它具有正确的字段,但将这些字段分配给对象“items”会导致“未定义”值

我一定是在范围上做错了,但我不知道出了什么问题。

请建议我如何使用此组件复制字段

谢谢

【问题讨论】:

  • 如果selectPartArray.prototype.filter()的结果,不就是一个数组吗?
  • 没有。 console.log(selectPart) 按预期返回一个对象
  • 我不太确定,也看不到任何console.log(selectPart)。我说这是一个数组,这就是为什么 selectPart.Descriptionundefined
  • 我在调试时添加了 console.log(selectPart) Code: "CS-KVM-8P" Cost: 1688.37 Description: "INTEGRATED DIGITAL 8-PORT KVM OVER IP SWITCH" Price: 8410 _id: "5d9eb36a9814894c5cea8f83" 看起来像一个对象
  • 非常感谢。你的建议解决了我的问题。非常感谢 Phil 帮助理解 'filter()' 返回的 'selectPart' 是一个数组,并感谢 Daniel 解释应该完全声明数据字段。 $set 方法也如前所述工作,但仅声明数据更简单。

标签: javascript vue.js methods


【解决方案1】:

在 Vue 2.x 中,properties added to objects are not reactive。您声明了 item 数据项,但没有属性 DescriptionPrice,并且后来使用简单的对象分配来分配这些属性,而 Vue 将无法跟踪。

有两种方法可以解决这个问题:

1. Declare all reactive properties upfront

data更改为

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

2. Use Vue.set()

改变

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

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

谢天谢地in Vue 3.x this caveat will be eliminated 并且所有添加到反应性对象的属性本身都会变成反应性的。

【讨论】:

  • OP 也可以只使用this.item = { Description: selectPart.Description, Price: selectPart.Price },这将是反应式的
【解决方案2】:

这是一个更优雅的问题解决方案。

将 .filter() 替换为 .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>

数据在哪里

  data() {
    return {
      item: {          
          Code: null,
          Description: null,
          Group: null,
          GroupCount: null,
          Quantity: null,
          ExtQuantity: null,
          Cost: null,
          Price: null,
          QuoteNumber: null},
      parts: [],
    };
  },
  computed: {
    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'});
        });
    }
  }
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    • 2017-12-05
    • 2012-06-04
    • 1970-01-01
    相关资源
    最近更新 更多