Vue异步数据传递到子组件props导致不能在子组件中显示

问题重现:

  我们经常在父组件中异步请求后端数据,然后通过props传递给子组件,这就导致子组件在渲染时不能及时拿到数据,导致一些bug。

  代码示例: 

父组件:
<template>
  <div class="container">
    <child :asyncData="asyncData"/>
  </div>
</template>

<script>
import child from './child.vue'
export default {
  components: {
    child
  },
  data: () => ({
    asyncData: ''
  }),
  mounted () {
    // setTimeout模拟异步数据
    setTimeout(() => {
      this.asyncData = 'async data'
      console.log('parent finish')
    }, 2000)
  }
}
</script>
子组件:
<template>
  <div class="container">
    子组件:{{ asyncData }}
  </div>
</template>

<script>
export default {
  props: {
    asyncData: {
      type: String,
      default: ''
    }
  },
  created () {
    console.log('data:' + this.asyncData)
  }
}
</script>

  运行结果:

可以看到,异步数据在子组件中渲染出来了,但是这个渲染有一个延迟,约2s,但是created中先拿到的是个空字符串,如果我们有在子组件中拿到props的数据,然后添加渲染逻辑的时候,就会产生Bug。

问题解决:

  1.使用watch来监听父组件改变的prop,书写初始化的逻辑,这时页面监听到props属性的修改就会渲染数据到页面,随着父组件值的修改而修改
<template>
  <div class="container">
    子组件:{{ asyncData }}
  </div>
</template>

<script>
export default {
  props: {
    asyncData: {
      type: String,
      default: ''
    }
  },
  watch: {
    asyncData () {
      console.log('data:' + this.asyncData)
    }
  },
  created () {
  },
}
</script>

  2. 使用v-if

<template>
  <div class="container">
    <child v-if="asyncData" :asyncData="asyncData"/>
  </div>
</template>

<script>
import child from './child.vue'
export default {
  components: {
    child
  },
  data: () => ({
    asyncData: ''
  }),
  mounted () {
    // setTimeout模拟异步数据
    setTimeout(() => {
      this.asyncData = 'async data'
      console.log('parent finish')
    }, 2000)
  }
}
</script>

  

posted @ 2020-12-24 11:56  我很怪  阅读(835)  评论(0编辑  收藏  举报