Vue 计算属性未按预期更新

Posted

技术标签:

【中文标题】Vue 计算属性未按预期更新【英文标题】:Vue computed property not updating as expected 【发布时间】:2018-03-05 10:26:09 【问题描述】:

我有数

  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 然后大声笑

【问题讨论】:

keywordsLeft: () =&gt; Math.max(0, total_keywords - keywords.length) 怎么样? 【参考方案1】:

这个问题对我来说经常发生。

为了解决这个问题,我尝试将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;
           
       
   , 

当 key 改变时,该组件(dom)将被重新渲染。

【讨论】:

【参考方案2】:

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

我猜问题出在更新实际数据的代码中。它以一种不适用于 Vue 的反应系统的方式进行。这发生在很多人身上:)

我建议您阅读这篇文章以获取整体指南 https://vuejs.org/v2/guide/reactivity.html 和此 https://vuejs.org/v2/guide/list.html#Array-Change-Detection 了解数组的陷阱。

添加:

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

我始终保持实例数据属性名称与外部/全局/非 Vue 数据不同。我说这样的话更好:

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

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

【讨论】:

当我删除一个关键字时我正在使用.... this.keywords.splice(i,1);视图更新正常,关键字被删除,但计数没有更新。是否有另一种方法我应该从数据对象中删除项目以强制更新计数?我记得在某个地方读到我必须做 Vue.set()。但我试过了,没有任何改变,所以只好改用一种方法。所以我现在不太确定如何使用计算属性。 听起来非常正确。请使用处理更新的代码更新您的问题!当代码可用时,指导您会容易得多:) 我添加了删除。它和我在评论中所说的完全一样。真的看不出有什么明显的问题……我的意思是……视图更新得很好。它会被删除。所以它的工作。只是计算,不重新计算。但是如果我把它放到一个方法中,那么它就可以工作了。 还添加了 this.$forceUpdate();拼接后不计算,重新计算 @KyleK 查看我答案中添加的部分。【参考方案3】:

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 计算属性未按预期更新的主要内容,如果未能解决你的问题,请参考以下文章

Vue 计算属性不会在更新其反应性依赖项时更新

Vue.js计算属性不更新

Vue计算属性

vue.js 是不是更新依赖于方法的计算属性?

OpenGL 属性偏移未按预期工作

错误时更新 Vue 中的计算属性(表单)?