2017-08-17 66 views
0

Vue的JS计算的财产不会被触发有了这个标记vue.js不会触发计算财产

<!-- language: lang-html --> 
<p>£{{plant_price}}</p> 

    <div v-if="selected.plant.variations.length > 0 "> 
     <select v-model="selected.plant.selected_variation" class="form-control"> 
     <!-- inline object literal --> 
     <option v-for="(variation, i) in selected.plant.variations" :selected="variation.id == selected.plant.selected_variation ? 'selected' : ''":value="variation.id"> 
      {{variation.name}} 
     </option> 
     </select> 
    </div> 

<!-- language: lang-js --> 
var app = new Vue({ 
    el: '#vueApp', 
    data: { 
    selected: { 
     type: {a: '' , b: ''}, 
     vehicle: '', 
     plant: { 
     } 
    }, 
    computed: { 
plant_price: function() { 
    if (this.selected.plant.variations.length > 0) { 
     var variant = _.find(this.selected.plant.variations, {id: this.selected.plant.selected_variation }); 
     return variant.price; 
    } else { 
    return this.selected.plant.price; 
    } 
} 
... 

selected.plant通过点击植物填充 - 触发updateSelected方法。

<div class="col-sm-4" v-for="(plant, i) in step2.plants"> 
      <div v-on:click="updateSelected(plant)" .... 

methods: { 
     updateSelected: function(plant) { 
      this.selected.plant = plant; // selected plant 
      if (this.selected.plant.variations.length > 0) { 
       this.selected.plant.selected_variation = this.selected.plant.variations[0].id; // set the selected ID to the 1st variation 

我已通过调试器检查过,可以看到所有正确的属性都可用。

selected:Object 
    type:Object 
    vehicle: "Truck" 
    plant:Object 
     id:26 
     price:"52" 
     regular_price:"100" 
     selected_variation:421 
     variations:Array[2] 
      0:Object 
       id:420 
       name:"small" 
       price:52000 
       regular_price:52000 
      1:Object 
       etc... 

我有一个计算的属性,它应该基于对selected.plant.selected_variation值更新plant_price

我抓住selected.plant.selected_variation并搜索变化以检索价格。如果不存在变化,则给出工厂价格。

我有一个方法在每个产品更新选定的工厂。点击产品填充selected.plant并触发计算的plant_price更新价格(因为selected.plant.selected_variation的值已更改)。

但是,计算出的plant_price不是由select触发的。选择一个新的变种做它应该的,它更新selected.plant.selected_variation。但我的工厂价格似乎并没有被它触发。


所以我通过un-nesting selected.plant.selected_variation重构我的代码。我现在把它挂在数据对象上,因为

data = { 
    selected_variation: '' 
    } 

并改变我的计算机属性来引用数据为this.selected_variation。我的计算属性现在可用?这对我来说没有意义?

回答

2

selected.plant.selected_variation不响应,虚拟机看不到任何更改,因为您已在创建虚拟机后设置它。

你可以把它与Vue.set()

当你的AJAX完成反应,称之为

Vue.set(selected, 'plant', {Plant Object}) 
+0

感谢@SpeekaDievs,对不起 - 我没有跟我描述它解释自己很好......我会更新我的问题 – Rob

+0

您的答案是正确的问题。我只是没有很好地描述它... – Rob

0

这里有两种方法可以做到这一点,你要对付的是一个嵌套的对象,因此,如果您想要的selected变更通知,你必须使用

this.$set(this.selected, 'plant', 'AJAX_RESULT') 

在我的使用setTimeout片断别人模拟Ajax调用的方法。

你可以做的另一种方式是,而不是把plant_pricecomputed属性,你可以观看嵌套属性的观察者selected 的变化,然后在handler更新plant_price,您可以检查出plant_price_from_watch片段。

Vue.component('v-select', VueSelect.VueSelect); 
 

 
const app = new Vue({ 
 
    el: '#app', 
 
    data: { 
 
    plant_price_from_watch: 'not available', 
 
    selected: { 
 
     type: {a: '' , b: ''}, 
 
     vehicle: "Truck" 
 
    } 
 
    }, 
 
    computed: { 
 
    plant_price() { 
 
     return this.setPlantPrice(); 
 
    } 
 
    }, 
 
    watch: { 
 
    selected: { 
 
     handler() { 
 
     console.log('changed'); 
 
     this.plant_price_from_watch = this.setPlantPrice(); 
 
     }, 
 
     deep: true 
 
    } 
 
    }, 
 
    created() { 
 
    setTimeout(() => { 
 
     this.$set(this.selected, 'plant', { 
 
     id: 26, 
 
     price: '52', 
 
     regular_price: '100', 
 
     selected_variation: 421, 
 
     variations: [ 
 
      { 
 
      id: 420, 
 
      name: "small", 
 
      price: 52000, 
 
      regular_price: 52000 
 
      }, 
 
      { 
 
      id: 421, 
 
      name: "smallvvsvsfv", 
 
      price: 22000, 
 
      regular_price: 22000 
 
      } 
 
     ] 
 
     }) 
 
    }, 3000); 
 
    }, 
 
    methods: { 
 
    setPlantPrice() { 
 
     if (!this.selected.plant) { 
 
     return 'not available' 
 
     } 
 
     if (this.selected.plant.variations.length > 0) { 
 
      const variant = _.find(this.selected.plant.variations, {id: this.selected.plant.selected_variation }); 
 
      return variant.price; 
 
     } else { 
 
     return this.selected.plant.price; 
 
     } 
 
    } 
 
    } 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script> 
 
<div id="app"> 
 
    <p>£{{plant_price}}</p> 
 
    <p>£{{plant_price_from_watch}}</p> 
 
    <div v-if="selected.plant && selected.plant.variations.length > 0 "> 
 
    <select v-model="selected.plant.selected_variation" class="form-control"> 
 
     <!-- inline object literal --> 
 
     <option v-for="(variation, i) in selected.plant.variations" :selected="variation.id == selected.plant.selected_variation ? 'selected' : ''":value="variation.id"> 
 
     {{variation.name}} 
 
     </option> 
 
    </select> 
 
    </div> 
 
</div>

+0

谢谢Kevlai22 - 恐怕我已经编辑了我的问题,因为我发布的问题充满了错误...请参阅编辑问题 – Rob

+0

@Rob我不太明白你的'updateSelected'方法,你传入的是'a'? – kevguy

+0

整个工厂对象。我有一个我渲染的植物列表(这个列表是通过ajax获得的)。在每个工厂,我都附上更新方法。我只是将整个工厂作为一个更新函数传递给更新函数。这会更新选定的工厂。我更新了我的问题以清晰地改变工厂 – Rob