vue中父子组件通过props传递数据,父组件数据ajax异步更新,子组件不动态更新的解决方案

用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是对象和数组时,在子组件内改变是会影响到父组件的。

 

 

 

 

 

你可能感兴趣的:(前端探究)