Vue computed property not updating as expected Vue computed property not updating as expected vue.js vue.js

Vue computed property not updating as expected


Computed properties are computed automatically and they're what you're supposed to use in a case like this.

I guess the problem lies somewhere in the code that updates your actual data. It is doing it in a way that doesn't work with Vue's reactivity system. This happens to many people :)

I suggest you to read this for overall guide https://vuejs.org/v2/guide/reactivity.html and this https://vuejs.org/v2/guide/list.html#Array-Change-Detection for gotchas on arrays.

Added:

I see your problem now. Inside the keywordsLeft computed property you're not referring to the Vue instance's data but actually to the original data. What I mean the keywords.length refers to the original keywords object and its length. Same with total_keywords - it doesn't refer to the Vue instance's data. You should use this.keywords and this.total_keywords.

I always keep the instance data property names different from the outside/global/not-Vue data. I'm saying something like this is better:

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

This way you cannot mix what you're referring to. Now you should refer to this.myKeywords etc. inside the Vue instance's scope.


K I solved it by just moving it into a method. Even though I feel this is wrong, it works. Not really sure the purpose of computed properties now. Since they seem to only compute once?

Anyway heres how I fixed it.

The HTML

You have {{ keywordsLeft() }} keywords left

The 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;       }   }}, 

Super simple.


This problem happened frequently for me.

To solve that, I tried to add key as that computed value and it worked perfectly.

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

When key is changed, that component(dom) will be re-rendered.