Vue计算值已经使我困惑了一段时间
何时会再次计算
condition1:
data() {
return {
cart:{
item:{
nums: 10,
price: 10
}
}
};
},
computed: {
total() {
return this.cart.item.nums * this.cart.item.price
}
},
methods:{
set(){
this.cart.item = {
nums: 5,
price: 5
}
}
}
计算即可使用
condition2:
data() {
return {
cart: [{
nums: 10,
price: 10
}]
};
},
computed: {
total() {
return this.cart[0].nums * this.cart[0].price
}
},
methods:{
set(){
this.cart[0] = {
nums: 5,
price: 5
}
}
}
计算无法正常工作
我知道这是解决方案,但是为什么呢?
methods:{
set(){
this.cart[0].nums = 5
this.cart[0].price = 5
}
}
}
为什么在condition2中没有看到它?
为什么Vue不想被观察?
答案 0 :(得分:6)
与对象和数组的反应性对Vue有点挑剔。使用其他变量,很容易检测到它们何时被更改,但是对于对象和数组,并非总是能够检测到对象/数组中的某些内容何时发生了更改。 (也就是说,没有代理,它将出现在Vue 3.x中)
在您的情况下,如果将total
标记为已更改,this.cart
被标记为已更改或者this.cart[0]
或this.cart[0].nums
被更改,this.cart[0].price
将重新计算。问题是您要替换this.cart[0]
中的对象。这意味着this.cart[0].price
和nums
不会更改,因为它们仍然指向旧对象。显然,this.cart[0]
和this.cart
未被标记为已更改,因此Vue仍然认为total
是最新的。
有几种方法可以解决此问题。一种是使用Vue的辅助方法来处理对象/数组,即Vue.set
,Vue.delete
。您可以使用this.$set
或this.$delete
在SFC中访问它们。 this.$set
明确将您作为第一个参数传递的内容标记为“更改”,因此您的总数也将被更新。
this.$set(this.cart, 0, {
nums: 2,
price: 100
});
另一种方法是修改对象本身,而不是替换它。由于您仍在使用同一对象,因此Vue将检测到this.cart[0]
已更改。
setItem() {
this.cart[0] = Object.assign(
this.cart[0],
{
nums: 5,
price: 5
}
);
}
另一种方法是使用许多数组方法之一。在您的情况下,可以使用Array.prototype.splice。由于这是一个函数调用,因此Vue可以检测到该函数已被调用,并且可以将正确的项目标记为已更改,这将触发依赖它的所有内容的更新。
this.cart.splice(0, 1, {
nums: 50,
price: 10
});