Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue computed property with an array not updating

I have this very simple case of an array property, which when updated doesn't make a computed property change jsfidle link: https://jsfiddle.net/fx1v4ze6/30/

Vue.component('test', {
 data: function() { 
     return {
        arr: this.myarray.slice()
     }
  },
      props:['myarray','secondprop'],
      template:'#arraybug',
      methods:{
        add:function(){
          this.myarray.push(1);
          this.secondprop+=1;
          this.arr.push(1);
        }
      },
      computed:{
        mycomputed: function(){
            return this.arr.length;
        },
        mycomputed2: function(){
            return this.secondprop;
        },
        mycomputed3: function(){
            return this.myarray.length;
        },
      }
     });

    var test = new Vue({
      el:"#test"});

HTML:

    <div id="test">
  <test :myarray="[1,2,3]" :secondprop="1"></test>
</div>
<template id="arraybug">
  <div >
    <button v-on:click="add()">
      click
    </button>
    {{mycomputed}} - {{mycomputed2}} - {{mycomputed3}}
  </div>
</template>

I would expect, since mycomputed is based on myarray, that any change to myarray will cause computed to update. What I have missed?

I've updated my exaple - mycomputed2 with secondprop is updated properly (for number). But myarray as a prop not.

like image 555
maque Avatar asked Jul 21 '18 10:07

maque


People also ask

Does Vue automatically update?

One of Vue's best features is reactivity. You change a variable, and Vue automatically updates what is rendered to the page. However, not everything in Vue is reactive by default.

How do computed properties work in Vue?

In Vue. js, computed properties enable you to create a property that can be used to modify, manipulate, and display data within your components in a readable and efficient manner. You can use computed properties to calculate and display values based on a value or set of values in the data model.

How do I Rerender components in Vue?

The best way to force Vue to re-render a component is to set a :key on the component. When you need the component to be re-rendered, you just change the value of the key and Vue will re-render the component.

What is the difference between watchers and computed property in Vuejs?

Computed properties are used to calculate the value of a property based on some other conditions. Watchers, on the other hand, are not primarily used for changing the value of a property; instead, they are used to notify you when the value has changed and let you perform certain actions based on these changes.


2 Answers

Props are not Reactive. Use data:

Vue.component('test', {
 props:['myarray'],
  data: function() { 
     return {
        arr: this.myarray.slice()
     }
  },
  template:'#arraybug',
  methods:{
    add:function(){

      this.arr.push(1);
    }
  },
  computed:{
    mycomputed: function(){
        let newLen = this.arr.length;
        return newLen;
    }
  }
 });

var test = new Vue({
  el:"#test"});

I'm copied props array to data.

like image 83
Vladimir Proskurin Avatar answered Sep 17 '22 20:09

Vladimir Proskurin


Vue can't detect the internal change of an array as mentioned here: https://vuejs.org/v2/guide/reactivity.html

Alternatively, if an array is used as a prop, in the component the prop is passed to, you can add a data field, and use methods (instead of computed) and watchers as shown in the example here: https://vuejs.org/v2/guide/computed.html#Watchers

like image 24
Ken H Avatar answered Sep 20 '22 20:09

Ken H