Vue 计算 属性 未按预期更新

Vue computed property not updating as expected

我有数

  You have {{ keywordsLeft }} keywords left

在我的 Vue 中。

var u = new Vue({
    el:'#app',
    data:{
        keywords:keywords,
        user:user,
        total_keywords:user.total_keywords,
    },
    computed: {
        keywordsLeft: function () {
           var left = total_keywords-keywords.length;
           if(left<=0){
             return 0;
           } else {
             return left;
           }
       }
   }, 
   methods: {
       deleteKeyword: function(keyword){
           var i = this.keywords.indexOf(keyword);
           this.keywords.splice(i,1);
       }
   }
       // rest of VUE code.

每当对数据进行更新时,计算值不会更新。我必须刷新页面才能做到这一点。我认为计算 属性 的目的是实时反应?我错过了什么吗?

我需要以某种方式显式更新它吗?重新计算是手动的?如果我很愚蠢,请原谅我,但如果它不是自动完成的,这似乎是一种浪费。不妨只使用 jquery 然后 lol

K 我通过将它移动到一个方法中解决了它。尽管我觉得这是错误的,但它确实有效。现在不太确定计算属性的目的。因为他们似乎只计算一次?

无论如何,这是我修复它的方法。

HTML

You have {{ keywordsLeft() }} keywords left

Vue

var u = new Vue({
el:'#app',
data:{
    keywords:keywords,
    user:user,
    total_keywords:user.total_keywords,
},
methods: {
    keywordsLeft: function () {
       var left = total_keywords-keywords.length;
       if(left<=0){
         return 0;
       } else {
         return left;
       }
   }
}, 

超级简单。

计算属性是自动计算的,它们是您在这种情况下应该使用的。

我想问题出在更新您的实际数据的代码中。它以一种不适用于 Vue 反应系统的方式进行。很多人都会遇到这种情况:)

我建议您阅读这篇文章作为整体指南https://vuejs.org/v2/guide/reactivity.html and this https://vuejs.org/v2/guide/list.html#Array-Change-Detection,了解数组上的陷阱。

已添加:

我现在明白你的问题了。在 keywordsLeft computed 属性 中,您指的不是 Vue 实例的数据,而是原始数据。我的意思是 keywords.length 指的是原始关键字对象及其长度。与 total_keywords 相同 - 它不引用 Vue 实例的数据。您应该使用 this.keywordsthis.total_keywords.

我总是保持实例数据 属性 名称与 outside/global/not-Vue 数据不同。我是说这样更好:

data: {
  myKeywords: keywords,
  myTotalKeywords: totalKeywords
  ...
}

这样你就不能混淆你所指的内容。现在你应该在 Vue 实例的范围内引用 this.myKeywords 等。

我经常遇到这个问题。

为了解决这个问题,我尝试将 key 添加为计算值,结果效果很好。

 <span :key="keywordsLeft">
    You have {{ keywordsLeft() }} keywords left
 </span>
...
 computed: {
        keywordsLeft: function () {
           var left = total_keywords-keywords.length;
           if(left<=0){
             return 0;
           } else {
             return left;
           }
       }
   }, 

更改键时,将重新渲染该组件(dom)。