使用此标记不会触发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...
我有一个计算属性,应根据plant_price
的值更新selected.plant.selected_variation
。
我抓住selected.plant.selected_variation
并搜索变体以检索价格。如果不存在差异,则给出工厂价格。
我在每个产品上都有一个方法来更新所选的工厂。单击该产品将填充selected.plant并触发计算的plant_price以更新价格(因为selected.plant.selected_variation的值已更改)。
但是,计算的plant_price不是由select触发的。选择一个新的变体做它应该的,它更新selected.plant.selected_variation。然而,我的plant_price似乎并没有被它触发。
所以我通过取消嵌套selected.plant.selected_variation来重构我的代码。我现在把它挂在数据对象上
data = {
selected_variation: ''
}
并更改我的计算机属性以引用数据作为this.selected_variation。我的计算属性现在有效???这对我没有意义吗?
答案 0 :(得分:2)
selected.plant.selected_variation不是被动的,VM看不到您对其所做的任何更改,因为您在创建VM后进行了设置。
你可以使它与Vue.set()
反应当您的AJAX完成后,请致电
Vue.set(selected, 'plant', {Plant Object})
答案 1 :(得分:0)
有两种方法可以做到这一点,你正在处理的是一个嵌套对象,所以如果你想通知selected
对你必须使用的其他人的更改
this.$set(this.selected, 'plant', 'AJAX_RESULT')
在代码段中,我使用setTimeout
方法中的created
来模拟Ajax调用。
另一种方法是将plant_price
作为computed
属性,而不是将selected
作为plant_price
属性,您可以观察嵌套属性的更改
观察者中handler
的{{1}},然后更新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>
。
/resources/assets/js/bootstrap.js
window.axios.defaults.headers.common = {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
'X-Requested-With': 'XMLHttpRequest'
};