🧋 问题描述
父组件的数据是请求后台所得,因为是异步数据,就会出现,父组件的值传递过去了,子组件加载不到,拿不到值的问题。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pn9unWDw-1693103033395)(https://note.youdao.com/yws/res/9/WEBRESOURCE717fc88846ccc13c044a1e223126def9)]](https://img-blog.csdnimg.cn/fbfa3a8b25894e8da23c5badc96da03c.png)
下面从同步数据传递和异步数据传递开始论述问题
🧋🧋1. 父组件传递的是同步数据
-  父组件 <template> <div class="parent"><div class="child"><props-children :data="dataJson"></props-children></div><input type="text" v-model="dataJson"/></div></template><script>import propsChildren from '../../component/props/props_children.vue'export default {components: { propsChildren },data(){ return{dataJson:"初始化数据"}},created(){console.log('父created',this.dataJson)},beforeuUpdate(){console.log('父beforeupdated',this.dataJson)},updated(){console.log('父updated',this.dataJson)},beforeDetroy(){console.log('父beforeDetroy',this.dataJson)},detroyed(){console.log('父detroyed',this.dataJson)}}</script><style scoped>.child{width:600px;height:600px;background:#eee;}</style>
-  子组件 <template><div>我是子组件<br><br><br>获取到父组件数据:{{data}}<br><br><br><input type="text" v-model="data"/></div></template> <script>export default {mounted(){console.log('子组件拿到数据',this.data)},props:{data:{default:"",require:true,type:String}},created(){console.log('子created',this.data)},beforeUpdate(){console.log('子beforeupdated',this.data)},updated(){console.log('子updated',this.data)},beforeDetroy(){console.log('子beforeDetroy',this.data)},detroyed(){console.log('子detroyed',this.data)}}</script><style></style>
如图所示:
-  在created阶段,父组件的初始化数据就已经传递给了子组件的props ![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qATnm0VP-1693103033400)(https://note.youdao.com/yws/res/1/WEBRESOURCEef9e584f878538fed9af15b7ffaba1e1)]](https://img-blog.csdnimg.cn/937bbd15a9b6421ea941ce1f50a07d7f.png) 
-  在created阶段,把获取的同步数据赋值给初始化数据,不会触发update钩子函数,子组件加载也能拿到数据 ![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jfcWIjPZ-1693103033403)(https://note.youdao.com/yws/res/4/WEBRESOURCE405319a84ce951d33284d54e96c59304)]](https://img-blog.csdnimg.cn/374b57e89edb4e478b89f63b5b9ecd05.png) ![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hh2isRv4-1693103033405)(https://note.youdao.com/yws/res/a/WEBRESOURCE9d4d920a472804c230ba7a9e6e35e28a)]](https://img-blog.csdnimg.cn/2bb0786333ec4b93a1eba14f03d18286.png) 
-  父组件更新数据(触发update),子组件也会同步更新,但是先更新的是子组件里的数据 ![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xEj4L6Jj-1693103033407)(https://note.youdao.com/yws/res/4/WEBRESOURCEb3e3c88a52735c3328ae1a51de1f7e74)]](https://img-blog.csdnimg.cn/fe660d82120349519ced5526d1d56908.png) 
-  子组件去更新props里的数据,父组件不但接收不到,而且还会报错 ![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vAQlqToa-1693103033409)(https://note.youdao.com/yws/res/6/WEBRESOURCE01aa38076fe0445148a42c134336fa56)]](https://img-blog.csdnimg.cn/a7b328b5364146e6a42afba780ca6541.png) 
父子组件声明周期执行顺序
加载渲染数据过程
父:beforeCrete --> 父:created --> 父:beforeMount --> 子:beforeCreate --> 子:created --> 子:beforeMount --> 子:mounted --> 父:mounted
更新渲染数据过程
父:beforeUpDate --> 子:beforeUpdate --> 子:updated --> 父:updated
销毁组件数据过程
父:beforeDestroy --> 子:beforeDestroy --> 子:destroyed --> 父:detroyed
但是,如果父组件获得是后台请求的异步数据就会出现问题。
🧋🧋 2.父组件传递的是异步数据
- 父组件
<template><div class="parent"><div class="child"><props-children :data="dataJson"></props-children></div><input type="text"  v-model="dataJson"/></div>
</template><script>
import propsChildren from '../../component/props/props_children.vue'
export default {components: { propsChildren },data(){ return{dataJson:"初始化数据"}},created(){// 模拟获取后台异步数据setTimeout(()=>{this.dataJson="父组件数据"},200)console.log('父created',this.dataJson)},beforeUpdate(){console.log('父beforeupdated',this.dataJson)},updated(){console.log('父updated',this.dataJson)},beforeDetroy(){console.log('父beforeDetroy',this.dataJson)},detroyed(){console.log('父detroyed',this.dataJson)}
}
</script><style scoped>.child{width:600px;height:300px;background:#eee;}
</style>
- 子组件
<template><div>我是子组件<br><br><br>获取到父组件数据:{{data}}<br><br><br><input type="text"  v-model="data"/></div>
</template> <script>
export default {mounted(){console.log('子组件拿到数据',this.data)},props:{data:{default:"",require:true,type:String}},created(){console.log('子created',this.data)},beforeUpdate(){console.log('子beforeupdated',this.data)},updated(){console.log('子updated',this.data)},beforeDetroy(){console.log('子beforeDetroy',this.data)},detroyed(){console.log('子detroyed',this.data)}
}
</script><style></style>![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vuRVJklG-1693103033410)(https://note.youdao.com/yws/res/a/WEBRESOURCE246c2ee57a93411eadd80b789a82321a)]](https://img-blog.csdnimg.cn/f97e8ef2682d47eabeb52f274bdac285.png)
 【产生问题的原因】
 父组件异步获取后台数据, 这时候加载渲染数据生命周期已经走完,只能更新数据,触发更新渲染生命周期,所以子组件加载时,永远只能拿到父组件的初始数据,拿不到父组件更新后的数据,但是,但是props是可以等的,页面是可以拿到异步的数据渲染的,所以就出现如上所示 的结果。
🧋解决问题
如何子组件加载获取不到父组件异步获取数据的问题
-  方案1:使用v-if控制子组件渲染的时机,父组件拿到后台异步数据后,再渲染子组件,加载子组件的时候就能得到父组件 的异步数据。 
-  方案2:子组件使用watch监听父组件传递过来的数据。 这种方式父组件正常传递数据即可,不要做什么代码处理,只要在子组件中加一个监听即可。 
🧋问题总结
子组件props如果绑定动态数据,默认只在加载时传递,也就是说只传一次。props绑定视图层,可以传多次。父组件created赋值同步数据不会触发updated,同步数据可以在created时就传递给子组件。父组件赋值异步数据,触发update,子组件也会在update才能拿到数据,所以加载时只能拿到父组件的初始化数据。