Why doesn't 'updated' get fired for a component when it has an array prop that is changed?

117 Views Asked by At

I created a child component with one prop of type Array. I expect the updated lifecycle event to fire whenever that array is modified from the parent using push(). This does not happen. I can see the changes take effect in the parent state, but those changes do not seem to get detected by the child component. What am I missing?

Example Code

See a 'working' demo on codepen.io

My view

<div id="app">
  <child :items="items"></child>
  <button type="button" v-on:click="addItem()">Add Item</button>
</div>

My script

// Child component
Vue.component('child', {
  template: '<div>{{itemCount}}</div>',
  props: {
   items: Array
  },
  data: function() { 
    return { itemCount: 0 }
  },
  updated: function() {
    this.itemCount = this.items.length;
  }
})

// Main app
var app = new Vue({
  el: '#app',
  data: {
    items: []
  },
  methods: {
    addItem: function() {
      this.items.push(Math.random());
    }
  }
});
2

There are 2 best solutions below

1
On BEST ANSWER

If you notice the documentation of the updated, it says:

Called after a data change causes the virtual DOM to be re-rendered and patched.

But in your case, you are not using items, anywhere in the DOM of the child component, so data change have no impacy on the virtual DOM and updated is not being called.

If you just add items in the div of child component, it will start working:

// Child component

Vue.component('child', {
  template: '<div>{{items}}::::{{itemCount}}</div>',
  props: {
   items: Array
  },
  ...
  ...
})

See working codepen here.

0
On

Try using a computed property instead the updated callback.

computed:{ itemCount(){ return this.items.length } }