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

举报
SHQ5785 发表于 2020/12/30 00:07:08 2020/12/30
【摘要】 问题描述 父组件通过Promise等其他异步方式获取异步数据,并传递给子组件,子组件直接显示没有问题,若对数据进行处理,则拿到的数据都是父组件初始值。 原因分析 父组件通过Promise等其他异步方式获取异步数据,在尚未等到数据返回时,子组件 created已经执行完毕,故此时子组件中的数据为父组件上次的数据。 父子组件的生命周期: 一、加载渲染过程 父be...

问题描述

父组件通过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

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200