写点什么

Vue 进阶(幺零六):子组件处理父组件异步值传递给子组件处理

用户头像
华强
关注
发布于: 1 小时前
Vue进阶(幺零六):子组件处理父组件异步值传递给子组件处理

一、问题描述

父组件通过Promise等其他异步方式获取异步数据,并传递给子组件,子组件直接显示没有问题,若对数据进行处理,则拿到的数据都是父组件初始值。

二、原因分析

父组件通过Promise等其他异步方式获取异步数据,在尚未等到数据返回时,子组件 created已经执行完毕,故此时子组件中的数据为父组件上次的数据。


父子组件的生命周期:



一、加载渲染过程


父 beforeCreate–> 父 created–>父 beforeMount–>子 beforeCreate–> 子 created–>子 beforeMount–>子 mounted–>父 mounted


二、子组件更新过程


父 beforeUpdate --> 子 beforeUpdate–> 子 updated–> 父 updated


三、销毁过程


父 beforeDestroy --> 子 beforeDestroy–> 子 destroyed–> 父 destroyed

三、解决措施

3.1 方法一

父组件


  <child :child-data="asyncData" v-if="asyncData"></child>
复制代码


asyncData有值得时候,再加载子组件。


评价:在asyncData为对象或数组元素,子组件获取对象属性或某一数组元素时,以上方法可行(不会报错),但仍会存在数据加载显示缓慢情形(及子组件首先显示的仍是上次父组件传值,然后才会渲染为当前父组件传值)。

3.2 方法二

子组件


watch:{  childData(val){      console.log('子组件 数据处理',val)  }}
复制代码


评价: 以上方法仍会出现方法一中的数据加载缓慢问题。

3.3 方法三

子组件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>
复制代码

3.4 方法四

使用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>
复制代码


这里使用了bus这个库,parent.vuechild.vue必须公用一个事件总线(也就是要引入同一个js,这个js定义了一个类似let bus = new Vue()的东西供这两个组件连接),才能相互触发。

3.5 其他方法

将数据存到store,子组件监听数据变化(watch/computed)。

四、其它场景问题

异步获取数据导致的报错的情况会在各个场景出现,比如:


  • 根据数据渲染dom,而对domjs操作的时候,会因为还没渲染出来而找不到相应的dom元素报错,这里可以用vue提供的$nextTick()函数,或者手动开个setTimeout定时器,延迟获取;

  • 使用better-scroll的时候因为dom没有渲染出来而无法获取滚动元素的高度,导致无法滚动,同样可以用vue提供的这个函数,等dom渲染完了后再初始化滚动。

五、拓展阅读

发布于: 1 小时前阅读数: 2
用户头像

华强

关注

No Silver Bullet 2021.07.09 加入

岂曰无衣 与子同袍

评论

发布
暂无评论
Vue进阶(幺零六):子组件处理父组件异步值传递给子组件处理