Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue computed property not updating as expected

I have a count

  You have {{ keywordsLeft }} keywords left

and in my 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.

Whenever an update is made to the data, the computed value doesnt update. I have to refresh the page to do it. I thought the purpose of computed property was live reactivity? Am I missing something?

Do I need to explicitly update it somehow? recompute is manually? Forgive me if Im being stupid, but this seems like a waste if its not done automatically. Might as well just use jquery then lol

like image 854
Kylie Avatar asked Sep 16 '25 21:09

Kylie


1 Answers

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://v2.vuejs.org/v2/guide/reactivity.html and this https://v2.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.

like image 130
pate Avatar answered Sep 18 '25 17:09

pate