Vue 计算问题 - 何时再次计算 [英] Vue computed issue - when will it compute again

查看:29
本文介绍了Vue 计算问题 - 何时再次计算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Vue 计算已经让我困惑了一段时间

Vue computed has already perplexed me for a while

什么时候再计算

条件 1:

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
    }
  }
}

计算会起作用

条件 2:

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
    }
  }
}

计算无效

我知道这是解决方案,但为什么呢?

I know this is the solution, but why?

methods:{
  set(){
    this.cart[0].nums = 5
    this.cart[0].price = 5
    }
  }
}

为什么在条件 2 中没有观察到?

why didn't it be observed in condition2 ?

为什么 Vue 不希望它被观察到?

why Vue don't want it be observed ?

推荐答案

Vue 对对象和数组的反应性有点挑剔.对于其他变量,很容易检测到它们何时发生更改,但是对于对象和数组,并不总是可以检测到对象/数组中的某些内容何时发生更改.(也就是说,没有代理,它将在 Vue 3.x 中出现)

Reactivity with objects and arrays is a bit finicky with Vue. With other variables it is easy to detect when they are changed, but with objects and arrays it is not always possible to detect whenever something in the object/array has been changed. (That is, without Proxies, which will come in Vue 3.x)

在您的情况下,如果 this.cart 被标记为已更改,this.cart[0] 将被重新计算,this.cart[0] 将被标记为更改或 this.cart[0].numsthis.cart[0].price 更改.问题是您要替换 this.cart[0] 中的对象.这意味着 this.cart[0].pricenums 不会改变,因为它们仍然指向旧对象.显然,this.cart[0]this.cart 没有被标记为已更改,因此 Vue 仍然认为 total 是最新的 -日期.

In your case, total will be recalculated if this.cart is marked as changed, this.cart[0] is marked as changed or if this.cart[0].nums or this.cart[0].price is changed. The problem is that you are replacing the object in this.cart[0]. This means that this.cart[0].price and nums do not change, because those still point to the old object. Apparently, this.cart[0] and this.cart are not marked as changed, so Vue still believes total to be up-to-date.

有几种方法可以解决这个问题.一种是使用Vue的辅助方法来处理对象/数组,即Vue.setVue.delete.您可以在 SFC 中使用 this.$setthis.$delete 访问它们.由于 this.$set 将您作为第一个参数传递的任何内容明确标记为已更改",因此您的总数也将更新.

There are several ways to get around this. One is to use Vue's helper methods to work with objects/arrays, namely Vue.set, Vue.delete. You can access them in your SFC with this.$set or this.$delete. As this.$set explicitly marks whatever you pass as first argument as "changed", your total will also be updated.

this.$set(this.cart, 0, {
  nums: 2,
  price: 100
});

另一种方法是修改对象本身,而不是替换它.由于您仍在使用同一个对象,Vue 将检测到 this.cart[0] 已更改.

Another way is to modify the object itself, rather than replacing it. Since you are still working with the same object, Vue will detect that this.cart[0] has changed.

setItem() {
  this.cart[0] = Object.assign(
    this.cart[0],
    {
      nums: 5,
      price: 5
    }
  );
}

另一种方法是使用多种数组方法中的一种.在您的情况下,您可以使用 Array.prototype.splice.由于这是一个函数调用,Vue 可以检测到该函数被调用,并可以将正确的项目标记为已更改,这将触发依赖它的任何内容的更新.

Another way is to use one of the many array methods. In your case, you could use Array.prototype.splice. As this is a function call, Vue can detect that the function is called and can mark the correct items as changed, which will trigger an update of anything that relies on it.

this.cart.splice(0, 1, {
  nums: 50,
  price: 10
});

这篇关于Vue 计算问题 - 何时再次计算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆