VueJs child component props not updating instantly

As far as I know, you should not need events to pass data from parent to child.

All you need is, in the child component: props: ['theProp']

And when using the child component in the parent: <child :theProp="someData"></child>

Now, wherever in the parent you change someData, the child component will react accordingly.

You don’t need events, you don’t need “watch”, you don’t need “ready”.


For example: after an AJAX call, in the parent’s “ready”, you load some data:

// at the parent component

data: function () {
  return {
    someData: {}
  }
},

ready: function () {
  var vm = this;
  $.get(url, function(response) {
    vm.someData = response;
  });
}

Now, you do not need anything else to pass the data to the child. It is already in the child as theProp!

What you really need to do is to have, in the child, something which reacts to data changes on its own theProp property.

Either in the interface:

<div v-if="theProp.id > 0">
  Loaded!
</div>

Or in JavaScript code:

// at the child component

computed: {
  // using a computed property based on theProp's value
  awesomeDate: function() {
    if (!this.theProp || (this.theProp.length === 0)) {
      return false;
    }
    if (!this.initialized) {
      this.initCalendar();
    }
    return this.theProp.someThing;
  }
}

Update 1

You can also, in the parent, render the child conditionally:

<child v-if="dataLoaded" :theProp="someData"></child>

Only set dataLoaded to true when the data is available.

Update 2

Or maybe your issue is related to a change detection caveat

Maybe you’re creating a new property in an object…

vm.someObject.someProperty = someValue

…when you should do…

vm.$set('someObject.someProperty', someValue)

…among other “caveats”.

Update 3

In VueJS 2 you are not restricted to templates. You can use a render function and code the most complex rendering logic you want.

Update 4 (regarding OP’s edit 2)

Maybe you can drop ready and use immediate option, so your initialization is in a single place:

watch: {
  someData: {
    handler: function (someData) {
      // check someData and eventually call
      this.initCalendar();
    },
    immediate: true
  }
}

Leave a Comment