用prop传递字符串、数字类型的值一般是没有问题的,不论数据在父组件中是同步获取的还是异步获取的,数据都可以通过prop响应式传递,子组件在监听到父组件值发生变化时会做出相应的改变。
父子组件传值测试
{{message}}
如果传递的数据是数组或对象呢?并且是在异步加载的情况下
- {{item}}
arr01:['数组1','数组2','数组3','数组4']
setTimeout(()=>{
this.arr01 = ['数组5','数组6','数组7','数组8']
},3000)
经过验证,同步和异步的数组、对象都可以正常响应式渲染。
接下来我们测试一下包含对象元素的数组可不可以正常响应式渲染。
- 饮料{{item.name}}还有{{item.count}}个
arr02 = [
{name:'wahah',count:23},
{name:'paise',count:54},
{name:'mengniu',count:36},
{name:'yili',count:44}
]
不管是同步还是异步过来的数组经过v-for渲染都没有问题,并且都可以响应式地渲染。
但是异步方式在使用数组地索引值直接渲染地时候会报undefined地错误,这是因为在DOM渲染地时候数组中还没有数据,却强行读取arr02[1]的属性,当然会报错
- 饮料{{arr02[0].name}}还有{{arr02[0].count}}个
- 饮料{{arr02[1].name}}还有{{arr02[1].count}}个
- 饮料{{arr02[2].name}}还有{{arr02[2].count}}个
- 饮料{{arr02[3].name}}还有{{arr02[3].count}}个
data: {
arr02:[]
},
created() {
setTimeout(()=>{
this.arr02 = [
{name:'wahah',count:23},
{name:'paise',count:54},
{name:'mengniu',count:36},
{name:'yili',count:44}
]
},3000)
}
这种报错会在异步数据获取到的时候正常渲染页面,不会有什么大的影响,但是如果异步数据的length长度小于html渲染的数量,也就是根本没有arr02[4]这个数据却渲染了,那么整个页面都不会展示出来。
父组件异步拿到的数据传到子组件还有一点要注意:如果子组件是直接使用父组件传递的数据没有什么问题,但如果子组件使用的是父组件传递过来数据后经过加工的数据(直接加工prop里的数据),那么你父组件数据更新时,子组件的数据是不会响应更新的。
这是父组件传过来的数字:{{num}}
这是copy父组件传过来的数字:{{num02}}
//在子组件中
props:['num'],
data(){
return{
num02:this.num
}
}
//在父组件中
data: {
num:undefined
},
created() {
setTimeout(()=>{
this.num = 189
},3000)
}
结果是3秒过后num的数据更新为189了,但是num02还是原来的undefined,没有更新。(如果是同步数据则没问题)
官方对此的解释是通过props传递数据是单向的。
是可以在子组件的computed中监听这种改变:
computed:{
num02(){
return this.num
}
}
这样就解决了不能对父组件异步传的数值进行加工的问题。
如果监听对象被多个数据影响,用computed监听,如果监听数据影响着多个数据,则用watch来监听。
注意:由于对象和数组是引用类型,指向同一个内存空间,所以props是对象和数组时,在子组件内改变是会影响到父组件的。