为什么v模型不能仅在特定字段上使用?

时间:2018-11-14 15:04:17

标签: javascript vue.js

我创建了一个包含以下字段的表单,该字段在此模块中起作用。除了v-model以外,下面列出的所有变量均使用net_rate进行实时更新。

  • 数量
  • 费率
  • 折扣
  • 净费率

我正在从API获取产品信息,并且在我的selectedItem: {}中创建了一个data对象。我可以使用v-modelnet_rate以外的数据对象绑定所有这些字段。

我不知道这是什么问题,因为自最近四天以来我一直在尝试解决此问题。但是这里是您可能需要帮助我解决问题的所有信息和代码。

数据:

data () {
    return {
        selectedItem: {},
    }
},

带有v模型绑定的标记

<div class="inline-form-group  col-sm-12 col-md-4 col-lg-1 text-right">
    <label for="quantity" style="color:teal;font-size:14px;">Qty.</label>
    <input type="text" ref="quantity" @input="setAmount()" @keydown.enter="$refs.rate.focus()" v-model="selectedItem.quantity" class="form-control text-right" />
</div>
<div class="inline-form-group col-sm-12 col-md-4 col-lg-1 text-right">
    <label for="cost" style="color:teal;font-size:14px;">Cost</label>
    <input type="text" ref="cost" disabled v-model="selectedItem.cost" class="form-control text-right" />
</div>
<div class="inline-form-group col-sm-12 col-md-4 col-lg-1 text-right">
    <label for="rate" style="color:teal;font-size:14px;">Rate</label>
    <input type="text" ref="rate" @keydown.enter="$refs.discount_perc.focus()" @input="setAmount()" v-model="selectedItem.price" class="form-control text-right" />
</div>
<div class="inline-form-group col-sm-12 col-md-4 col-lg-1 text-right">
    <label for="discount_perc" style="color:teal;font-size:14px;">Dis %</label>
    <input type="text" ref="discount_perc" @keydown.enter="$refs.net_rate.focus()" @input="setAmount()" v-model="selectedItem.discount_perc" class="form-control text-right" />
</div>
<div class="inline-form-group col-sm-12 col-md-4 col-lg-1 text-right">
    <label for="net_rate" style="color:teal;font-size:14px;">Net Rate</label>
    <input type="text" ref="net_rate" @input="setAmount()" v-model="selectedItem.net_rate" class="form-control text-right" />
</div>

您可以在此处忽略cost,因为没有在任何地方使用它。它是预定义的,不会在模块中更改。

请注意,所有其他变量(例如ratediscount_percquantity)都已成功绑定并可以正常工作。但是仅net_rate字段不起作用。这是此计算中使用的函数。

功能

setAmount: function () {
    if(this.selectedItem.net_rate !== this.selectedItem.price){
        var discount_percAmount = this.selectedItem.discount_perc?(this.selectedItem.discount_perc*this.selectedItem.price)/100:0;
        this.selectedItem.net_rate = this.selectedItem.price-discount_percAmount;
    }

    if(this.selectedItem.size_breadth > 0 && this.selectedItem.size_length > 0){
        this.selectedItem.item_amt = this.selectedItem.net_rate*this.selectedItem.quantity*this.selectedItem.size_breadth*this.selectedItem.size_length;
    } else {
        this.selectedItem.item_amt = this.selectedItem.net_rate*this.selectedItem.quantity;
    }
},

由于这个错误,我感到非常沮丧,我们将提供任何帮助。

2 个答案:

答案 0 :(得分:1)

如@connexo在评论中所述,

在对象上,Vue cannot detect changes of properties。它只能检测对象本身的引用是否更改。这是由于Javascript的性质。您需要执行obj.myProp = 10;

来代替Vue.set(obj, 'myProp', 10);

您将需要执行以下操作:

setAmount: function () {
    if(this.selectedItem.net_rate !== this.selectedItem.price){
        var discount_percAmount = this.selectedItem.discount_perc?(this.selectedItem.discount_perc*this.selectedItem.price)/100:0;
        Vue.set(this.selectedItem, 'net_rate', this.selectedItem.price-discount_percAmount);
    }

    if(this.selectedItem.size_breadth > 0 && this.selectedItem.size_length > 0){
        Vue.set(this.selectedItem, 'item_amt', this.selectedItem.net_rate*this.selectedItem.quantity*this.selectedItem.size_breadth*this.selectedItem.size_length);
    } else {
        Vue.set(this.selectedItem, 'item_amt', this.selectedItem.net_rate*this.selectedItem.quantity);
    }
},

答案 1 :(得分:0)

connexo在他的评论中说得很完美。

Vue当前不知道此属性的存在,如下所述。

来源:https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats

  

由于现代JavaScript的局限性(以及Object.observe的放弃),Vue无法检测到属性的添加或删除。由于Vue在实例初始化期间执行getter / setter转换过程,因此数据对象中必须存在一个属性,以便Vue对其进行转换并使其具有反应性。例如:

var vm = new Vue({
  data: {
    a: 1
  }
})
// `vm.a` is now reactive

vm.b = 2
// `vm.b` is NOT reactive

我们需要告诉Vue这个值存在并且我们希望它是反应性的,所以让我们在您的数据对象中对其进行修改。

data () {
    return {
        selectedItem: {
          quantity: 0,
          cost: 0,
          price: 0,
          discount_perc: 0,
          net_rate: 0,
        },
    }
},