Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vuejs mount the child components only after data has been loaded

What am trying to achieve is to pass data as props in my children components but this data is loaded from the server so it takes a while to load.

I would now like to only mount the children components when the data is fully loaded

SO currently am doing this

IN the parent component

<template>
  <child-cmp :value="childdata"></child-cmp>
</template>

<script>
  export default{
    data(){
       childdata : [];
     },

     methods:{
      fetchINitData(){
        //fetch from server then
         this.childdata = res.data.items;
         console.log(res.data.items) //has some values

       }

     }


   components:{
     childcmp
    },

   mounted(){
     this.fetchINitData();


     }
    }
 </script>

NOw in my child component

<script>
export default{
   props:["value];

    mounted(){
      console.log(this.value) //this is always empty
     } 

     }

</script>

As from the above example the data passed as props is always empty on the children component. How do i only mount the child component after data has been received or how do i ensure that the childs component get the latest data changed.

like image 552
Geoff Avatar asked Oct 13 '17 13:10

Geoff


2 Answers

Use <template v-if="childDataLoaded">,And load your child component after getting data like this

<template>
  <template v-if="childDataLoaded">
    <child-cmp :value="childdata"></child-cmp>
  </template>
</template>

<script>
  export default{
    data(){
        childDataLoaded: false,
        childdata : [];
     },
     methods:{
      fetchINitData(){
        //fetch from server then
         this.childdata = res.data.items;
         this.childDataLoaded = true;
         console.log(res.data.items) //has some values
       }
     }
   components:{
     childcmp
    },
   mounted(){
     this.fetchINitData();
     }
    }
 </script>

Here is the Nice and cleaner way to update child component.

var child = Vue.extend({
    template: "<div>Child Component : {{name}} <div v-if='loading'>Loading...</div></div>",
    props: ['name','loading']
});
var app = new Vue({
    el: "#vue-instance",
    data: {
        name: "Niklesh",
        loading: true
    },
    mounted() {
    		var vm =  this;
    		setTimeout(function() {
        	vm.name = "Raut";
          vm.loading = false;
				}, 1000);
    },
    components: {
        child
    },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.1/vue.js"></script>
<div id="vue-instance">
    <child :name="name" :loading="loading"></child>
</div>
like image 197
Niklesh Raut Avatar answered Oct 21 '22 01:10

Niklesh Raut


Just Bind key to child-cmp you get reactive output. this is simplest method of reactivity in Vue js.

<template>
  <child-cmp :key="childdata" :value="childdata"></child-cmp>
</template>

<script>
  export default{
    data(){
       childdata : [];
     },

     methods:{
      fetchINitData(){
        //fetch from server then
         this.childdata = res.data.items;
         console.log(res.data.items) //has some values
       }
     }

   components:{
     childcmp
    },

   mounted(){
     this.fetchINitData();
     }
    }
 </script>
like image 5
Rahul Hirve Avatar answered Oct 21 '22 03:10

Rahul Hirve