问题描述
父组件的数据是请求后台所得,因为是异步数据,就会出现,父组件的值传递过去了,子组件加载不到,拿不到值的问题。
下面从同步数据传递和异步数据传递开始论述问题
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
在created阶段,把获取的同步数据赋值给初始化数据,不会触发update钩子函数,子组件加载也能拿到数据
父组件更新数据(触发update),子组件也会同步更新,但是先更新的是子组件里的数据
子组件去更新props里的数据,父组件不但接收不到,而且还会报错
父子组件声明周期执行顺序
加载渲染数据过程
父: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>
【产生问题的原因】
父组件异步获取后台数据, 这时候加载渲染数据生命周期已经走完,只能更新数据,触发更新渲染生命周期,所以子组件加载时,永远只能拿到父组件的初始数据,拿不到父组件更新后的数据,但是,但是props是可以的等的,页面是可以拿到异步的数据渲染的,所以就出现如下所示 的结果。
如何子组件加载获取不到父组件异步获取数据的问题
方案1:使用v-if控制子组件渲染的时机,父组件拿到后台异步数据后,再渲染子组件加载的时候就能得到父组件 的异步数据。
方案2:子组件使用watch监听父组件传递过来的数据。
这种方式父组件正常传递数据即可,不要做什么代码处理,只要在子组件中加一个监听即可。