父子组件的钩子并不会等待请求返回,请求是异步的,VUE 设计也不能因为请求没有响应而不执行后面的钩子。所以,我们必须通过 v-if 来控制子组件钩子的执行时机。
在父组件的 created 中发请求获取数据,通过props传递给子组件。子组件在 created 或者mounted中拿父组件传递过来的数据 ,这样处理是有问题的。
原因:
在父组件调用接口传递数据给子组件时,接口响应显然是异步的。这会导致无论你在父组件哪个钩子发请求,在子组件哪个钩子接收数据。都是取不到的。当子组件的mounted都执行完之后,此时可能父组件的请求才返回数据。会导致:从父组件传递给子组件的数据是 undefined
注意:mounted 不会保证所有的子组件也都被一起挂载。如果希望等到整个视图都渲染完毕,可以在 mounted 内部使用 vm.$nextTick
解决办法
方法一: 在渲染子组件的时候加上一个条件,data1 是父组件调用接口返回的数据。当有数据的时候再去渲染子组件。这样就会形成天然的阻塞。在父组件的 created 中的请求返回数据后,才会执行子组件的 created,mounted。最后执行父组件的mounted。
<div class="test">
<children v-if="data1" :data="data1" />
</div>
方法二:
在子组件中 watch 监听,父组件获取到值,这个值就会变化,自然是可以监听到的。
从父组件点击调用接口并显示子组件,子组件拿到数据并监听在 watch 中调用方法并显示
props:['data1'],
watch:{
data1:{
deep: true,
handler: function(newval, oldval){
this.$nextTick(() => {
this.data1 = newval
this.showData1(this.data1)
})
}
}
}
以下为子组件。data1 是从父组件传递过来的数据。在 created,mounted中都拿不到父组件调用接口返回的data1。只能 watch 监听 data1,并调用方法渲染子组件。