2017-08-17 64 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