Vue进阶(幺零六):子组件处理父组件异步值传递给子组件处理
问题描述
父组件通过Promise等其他异步方式获取异步数据,并传递给子组件,子组件直接显示没有问题,若对数据进行处理,则拿到的数据都是父组件初始值。
原因分析
父组件通过Promise等其他异步方式获取异步数据,在尚未等到数据返回时,子组件 created已经执行完毕,故此时子组件中的数据为父组件上次的数据。
父子组件的生命周期:
一、加载渲染过程
父beforeCreate–> 父created–>父beforeMount–>子 beforeCreate–> 子 created–>子 beforeMount–>子 mounted–>父mounted
- 1
二、子组件更新过程
父beforeUpdate --> 子 beforeUpdate–> 子 updated–> 父updated
- 1
三、销毁过程
父beforeDestroy --> 子 beforeDestroy–> 子 destroyed–> 父destroyed
- 1
解决
方法一
父组件
<child :child-data="asyncData" v-if="asyncData"></child>
- 1
当asyncData有值得时候,再加载子组件。
评价:在asyncData为对象或数组元素,子组件获取对象属性或某一数组元素时,以上方法可行(不会报错),但仍会存在数据加载显示缓慢情形(及子组件首先显示的仍是上次父组件传值,然后才会渲染为当前父组件传值)。
方法二
子组件
watch:{
childData(val){ console.log('子组件 数据处理',val)
}
}
- 1
- 2
- 3
- 4
- 5
评价: 以上方法仍会出现方法一中的数据加载缓慢问题。
方法三
子组件watch computed data 相结合
<template>
<div>
子组件
<p>{{test}}</p>
</div>
</template>
<script>
export default {
props: ['tableData'],
data: () => ({ test: ''
}),
watch: { tableData (val) { this.dataResult = val }
},
computed: { dataResult : { set (value) { this.update() this.test = value }, get () { return this.test } }
},
methods: { update () { console.log(this.childObject) // {items: [1,2,3]} }
}
}
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
方法四
使用emit,on,bus相结合
<template>
<div>
子组件
<p>{{test}}</p>
</div>
</template>
<script>
export default {
props: ['childObject'],
data: () => ({ test: ''
}),
created () { // 绑定 this.$bus.on('triggerChild', (parmas) => { this.test = parmas.items[0] // 1 this.updata() })
},
methods: { updata () { console.log(this.test) // 1 }
}
}
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
这里使用了bus这个库,parent.vue和child.vue必须公用一个事件总线(也就是要引入同一个js,这个js定义了一个类似let bus = new Vue()的东西供这两个组件连接),才能相互触发。
其他方法
将数据存到store,子组件监听数据变化(watch/computed)。
其它场景问题
异步获取数据导致的报错的情况会在各个场景出现,比如:
- 根据数据渲染dom,而对dom有js操作的时候,会因为还没渲染出来而找不到相应的dom元素报错,这里可以用vue提供的
$nextTick()
函数,或者手动开个setTimeout
定时器,延迟获取; - 使用better-scroll的时候因为dom没有渲染出来而无法获取滚动元素的高度,导致无法滚动,同样可以用vue提供的这个函数,等dom渲染完了后再初始化滚动。
文章来源: shq5785.blog.csdn.net,作者:No Silver Bullet,版权归原作者所有,如需转载,请联系作者。
原文链接:shq5785.blog.csdn.net/article/details/105447960
- 点赞
- 收藏
- 关注作者
评论(0)