vue父組件傳遞props異步數據到子組件遇到的問題

狀況1:
 父組件parent.vue

// asyncData為異步獲取的數據,想傳遞給子組件使用
<template>
 <div>
  父組件
  <child :child-data="asyncData"></child>
 </div>
</template>
 
<script>
 import child from '../demo/children.vue'
 export default {
  data: () => ({
   asyncData: ''
  }),
  components: {
   child
  },
  created () {
  },
  mounted () {
   // setTimeout模擬異步數據
   setTimeout(() => {
    this.asyncData = ' async data'
    console.log('parent 組件結束')
   }, 2000)
  }
 }
</script>

子組件child.vue

<template>
 <div>
  子組件{{childData}}
 </div>
</template>
 
<script>
 export default {
  props: ['childData'],
  data: () => ({
  }),
  created () {
   console.log("子組件created-----   "+this.childData) // 空值
  },
  methods: {
  }
 }
</script>

子組件的html中的{{childData}}的值會隨著父組件的值而改變

在這里插入圖片描述

但是created里面的卻不會發生改變(生命周期問題)
在這里插入圖片描述

案例二
  parent.vue

<template>
 <div>
  父組件
  <child :child-object="asyncObject"></child>
 </div>
</template>
 
<script>
import child from '../demo1/children.vue'
 export default {
  data: () => ({
   asyncObject: ''
  }),
  components: {
   child
  },
  created () {
  },
  mounted () {
   // setTimeout模擬異步數據
   setTimeout(() => {
    this.asyncObject = {'items': [1, 2, 3]}
    console.log('parent 結束')
   }, 2000)
  }
 }
</script>

子組件 children

<template>
 <div>
  子組件<!--這里很常見的一個問題,就是{{childObject}}可以獲取且沒有報錯,但是{{childObject.items[0]}}不行,往往有個疑問為什么前面獲取到值,后面獲取不到呢?-->
  <p>{{childObject.items[0]}}</p>
 </div>
</template>
 
<script>
 export default {
  props: ['childObject'],
  data: () => ({
  }),
  created () {
   console.log(this.childObject) // 空值
  },
  methods: {
  }
 }
</script>

created里面的卻不會發生改變, 子組件的html中的{{{childObject.items[0]}}的值雖然會隨著父組件的值而改變,但是過程中會報錯。

是因為:首先傳過來的是空,然后再異步刷新值,也就是開始時候childObject.items[0]等同于''.item[0]這樣的操作,
所以就會報下面的錯:


在這里插入圖片描述

解決辦法:
1、使用v-if可以解決報錯問題和created為空問題
父組件parent

<template>
 <div>
  父組件
  <child :child-object="asyncObject"  v-if="flag"></child>
 </div>
</template>
 
<script>
import child from '../demo1/children.vue'
 export default {
  data: () => ({
   asyncObject: '',
   flag:false
  }),
  components: {
   child
  },
  created () {
  },
  mounted () {
   // setTimeout模擬異步數據
   setTimeout(() => {
    this.asyncObject = {'items': [1, 2, 3]}
    this.flag= true
    console.log('parent 結束')
   }, 2000)
  }
 }
</script>

子頁面 children

<template>
 <div>
  子組件<!--這里很常見的一個問題,就是{{childObject}}可以獲取且沒有報錯,但是{{childObject.items[0]}}不行,往往有個疑問為什么前面獲取到值,后面獲取不到呢?-->
  <p>{{childObject.items[0]}}</p>
 </div>
</template>
 
<script>
 export default {
  props: ['childObject'],
  data: () => ({
  }),
  created () {
    console.log("子組件create-----"+JSON.stringify(this.childObject)) // 空值
  },
  methods: {
  }
 }
</script>
在這里插入圖片描述

2、子組件使用watch來監聽父組件改變的prop,使用methods來代替created

子組件 children

<template>
 <div>
  子組件<!--這里很常見的一個問題,就是{{childObject}}可以獲取且沒有報錯,但是{{childObject.items[0]}}不行,往往有個疑問為什么前面獲取到值,后面獲取不到呢?-->
  <p>{{test}}</p>
 </div>
</template>
 
<script>
 export default {
  props: ['childObject'],
  data: () => ({
       test: ''
  }),
   watch: {
     'childObject.items': function (n, o) {
      this.test = n[0]
      this.updata()
     }
    },
  methods: {
     updata () { // 既然created只會執行一次,但是又想監聽改變的值做其他事情的話,只能搬到這里咯
      console.log(this.test)// 1
     }
    }
 }
</script>
在這里插入圖片描述

3、子組件watch computed data 相結合(麻煩)

子組件children

<template>
 <div>
  子組件<!--這里很常見的一個問題,就是{{childObject}}可以獲取且沒有報錯,但是{{childObject.items[0]}}不行,往往有個疑問為什么前面獲取到值,后面獲取不到呢?-->
   <p>{{test}}</p>
 </div>
</template>
 
<script>
 export default {
    props: ['childObject'],
    data: () => ({
     test: ''
    }),
    watch: {
     'childObject.items': function (n, o) {
      this._test = n[0]
     }
    },
 computed: {
    _test: {
     set (value) {
      this.update()
      this.test = value
     },
     get () {
      return this.test
     }
    }
   },
  methods: {
   update () {
      console.log(this.childObject) // {items: [1,2,3]}
     }
  }
 }
</script>
在這里插入圖片描述

4、使用prop default來解決{{childObject.items[0]}}

父組件:

<template>
 <div>
  父組件
  <child :child-object="asyncObject"></child>
 </div>
</template>
 
<script>
 import child from  '../demo4/children.vue'
 export default {
  data: () => ({
   asyncObject: undefined // 這里使用null反而報0的錯
  }),
  components: {
   child
  },
  created () {
  },
  mounted () {
   // setTimeout模擬異步數據
   setTimeout(() => {
    this.asyncObject = {'items': [1, 2, 3]}
    console.log('parent finish')
   }, 2000)
  }
 }
</script>

子組件:

<template>
 <div>
  子組件<!--1-->
  <p>{{childObject.items[0]}}</p>
 </div>
</template>
 
<script>
 export default {
  props: {
   childObject: {
    type: Object,
    default () {
     return {
      items: ''
     }
    }
   }
  },
  data: () => ({
  }),
  created () {
   console.log(this.childObject) // {item: ''}
  }
 }
</script>
在這里插入圖片描述
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容