亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

詳解vue2父組件傳遞props異步數據到子組件的問題

2019-11-19 16:13:30
字體:
來源:轉載
供稿:網友

測試環境:vue v2.3.3, vue v2.3.1

案例一

父組件parent.vue

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

子組件child.vue

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

上面按照這里的解析,子組件的html中的{{childData}}的值會隨著父組件的值而改變,但是created里面的卻不會發生改變(生命周期問題)

案例二

parent.vue

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

child.vue

<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]這樣的操作,所以就會報下面的錯vue.esm.js?8910:434 [Vue warn]: Error in render function: "TypeError: Cannot read property '0' of undefined"

針對二的解決方法:

使用v-if可以解決報錯問題,和created為空問題

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

child.vue

<template> <div>  子組件  <!--不報錯-->  <p>{{childObject.items[0]}}</p> </div></template><script> export default {  props: ['childObject'],  data: () => ({  }),  created () {   console.log(this.childObject)// Object {items: [1,2,3]}  },  methods: {  } }</script>

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

parent.vue

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

child.vue

<template> <div>  子組件<!--1-->  <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>

子組件watch computed data 相結合,有點麻煩

parent.vue

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

child.vue

<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>

使用emit,on,bus相結合

parent.vue

<template> <div>  父組件  <child></child> </div></template><script> import child from './child' export default {  data: () => ({  }),  components: {   child  },  mounted () {   // setTimeout模擬異步數據   setTimeout(() => {    // 觸發子組件,并且傳遞數據過去    this.$bus.emit('triggerChild', {'items': [1, 2, 3]})    console.log('parent finish')   }, 2000)  } }</script>

child.vue

<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.vue和child.vue必須公用一個事件總線(也就是要引入同一個js,這個js定義了一個類似let bus = new Vue()的東西供這兩個組件連接),才能相互觸發

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

parent.vue

<template> <div>  父組件  <child :child-object="asyncObject"></child> </div></template><script> import child from './child' 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>

child.vue

<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>

在說用vuex解決方法的時候,首先看看案例三

案例三

main.js

import Vue from 'vue'import App from './App'import router from './router'import VueBus from 'vue-bus'import index from './index.js'Vue.use(VueBus)Vue.config.productionTip = falseimport Vuex from 'vuex'Vue.use(Vuex)const store = new Vuex.Store({ modules: {  index }})/* eslint-disable no-new */new Vue({ el: '#app', store, router, template: '<App/>', components: { App }})

index.js

const state = { asyncData: ''}const actions = { asyncAction ({ commit }) {  setTimeout(() => {   commit('asyncMutation')  }, 2000) }}const getters = {}const mutations = { asyncMutation (state) {  state.asyncData = {'items': [1, 2, 3]} }}export default { state, actions, getters, mutations}

parent.vue

<template> <div>  父組件  <child></child> </div></template><script> import child from './child' export default {  data: () => ({  }),  components: {   child  },  created () {   this.$store.dispatch('asyncAction')  },  mounted () {  } }</script>

child.vue

<template> <div>  子組件  <p>{{$store.state.index.asyncData.items[0]}}</p> </div></template><script> export default {  data: () => ({  }),  created () {  },  methods: {  } }</script>

{{$store.state.index.asyncData.items[0]}}可以取到改變的值,但是過程中還是出現這樣的報錯,原因同上

復制代碼 代碼如下:

[Vue warn]: Error in render function: "TypeError: Cannot read property '0' of undefined"

所以這里的解決方法是:vuex結合computed、mapState或者合computed、mapGetters

parent.vue

<template> <div>  父組件  <child></child> </div></template><script> import child from './child' export default {  data: () => ({  }),  components: {   child  },  created () {   this.$store.dispatch('asyncAction')  },  mounted () {  } }</script>

child.vue

<template> <div>  子組件  <p>{{item0}}</p>  <p>{{item}}</p> </div></template><script> import { mapState, mapGetters } from 'vuex' export default {  data: () => ({   test: ''  }),  computed: {   ...mapGetters({    item: 'getAsyncData'   }),   ...mapState({    item0: state => state.index.asyncData   })  },  created () {  },  methods: {  } }</script>

index.js

const state = { asyncData: ''}const actions = { asyncAction ({ commit }) {  setTimeout(() => {   commit('asyncMutation', {'items': [1, 2, 3]})// 作為參數,去調用mutations中的asyncMutation方法來對state改變  }, 2000) }}const getters = { getAsyncData: state => state.asyncData}const mutations = { asyncMutation (state, params) {  state.asyncData = params.items[0] // 此時params={'items': [1, 2, 3]}被傳過來賦值給asyncData,來同步更新asyncData的值,這樣html就可以拿到asyncData.items[0]這樣的值了 }}export default { state, actions, getters, mutations}

注意上面的

....commit('asyncMutation', {'items': [1, 2, 3]})...state.asyncData = params.items[0]

如果寫成這樣的話

commit('asyncMutation')state.asyncData = {'items': [1, 2, 3]}

首先asyncAction是個異步的操作,所以asyncData默認值為空,那么還是導致,child.vue這里報0的錯

<template> <div>  子組件  <p>{{item0}}</p>  <p>{{item}}</p> </div></template>

不過根據以上的案例,得出來一個問題就是異步更新值的問題,就是說開始的時候有個默認值,這個默認值會被異步數據改變,比如說這個異步數據返回的object,如果你用props的方式去傳遞這個數據,其實第一次傳遞的空值,第二次傳遞的是更新后的值,所以就出現{{childObject.items[0]}}類似這種取不到值的問題,既然說第一次是空值,它會這樣處理''.items[0],那么我們是不是可以在html判斷這個是不是空(或者在computed來判斷是否為默認值),所以把案例二的child.vue

<template> <div>  <p>{{childObject != '' ? childObject.items[0]: ''}}</p> </div></template><script> export default {  props: ['childObject'],  data: () => ({  }),  created () {   console.log(this.childObject) // 空值  },  methods: {  } }</script>

這樣是可以通過不報錯的,就是created是空值,猜想上面vuex去stroe也可以也可以這樣做

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
有码中文亚洲精品| 2019亚洲日韩新视频| 97久久精品人人澡人人爽缅北| 97久久伊人激情网| 欧美黑人国产人伦爽爽爽| 亚洲一区二区三区xxx视频| 大胆人体色综合| 日本精品久久久久久久| 国产精品女视频| 欧美一级免费视频| 福利二区91精品bt7086| 欧美精品久久久久| 韩国一区二区电影| 久久久久国产视频| 国产区精品在线观看| 国产精品久久久久久网站| 亚洲欧美日韩在线高清直播| 欧美激情在线播放| 久久亚洲欧美日韩精品专区| 国模视频一区二区| 欧美黄色三级网站| 亚洲黄色av女优在线观看| 91久久久在线| 欧美激情一区二区三区在线视频观看| 欧美电影电视剧在线观看| 欧美美最猛性xxxxxx| 综合网日日天干夜夜久久| 久久久国产精品亚洲一区| 国模gogo一区二区大胆私拍| 欧洲成人在线视频| 欧美成人一区在线| 欧美激情免费在线| 午夜精品理论片| 成人黄色网免费| 国产69精品99久久久久久宅男| 久久久精品网站| 亚洲精品成人av| 日韩美女激情视频| 亚洲无限乱码一二三四麻| 97视频在线观看免费| 日韩在线观看免费全集电视剧网站| 2018日韩中文字幕| 国产精品极品尤物在线观看| 国产精品人人做人人爽| 国产一区二区三区欧美| 国内精品伊人久久| 欧美最猛黑人xxxx黑人猛叫黄| 黄色一区二区在线| 日韩在线视频线视频免费网站| 精品视频久久久久久| 大伊人狠狠躁夜夜躁av一区| 成人精品福利视频| 热re99久久精品国产66热| 日韩中文第一页| 国产做受69高潮| 国产精品福利在线观看| 亚洲国产天堂久久国产91| 欧美午夜丰满在线18影院| 91精品国产91久久久久久久久| 日韩视频永久免费观看| 1769国内精品视频在线播放| 韩国19禁主播vip福利视频| 亚洲精品国产精品国自产观看浪潮| 亚洲老头同性xxxxx| 欧美日韩成人在线视频| 久久久国产一区| 正在播放国产一区| 久久综合国产精品台湾中文娱乐网| 国产日韩欧美在线| 国产啪精品视频网站| 一本色道久久88综合亚洲精品ⅰ| 国产精品美女在线观看| 91免费看片在线| 亚洲精品国产品国语在线| 在线观看不卡av| 日韩av在线网站| 视频在线一区二区| 欧美日韩国产色| 国产精品扒开腿做| 久久国产精品首页| 久久夜精品香蕉| 日韩美女毛茸茸| 国产午夜精品麻豆| 亚洲黄色成人网| 国产成人精品a视频一区www| 日韩av在线影视| 91精品国产色综合久久不卡98| 在线观看欧美视频| 一个人看的www久久| 自拍亚洲一区欧美另类| 亚洲第一区第二区| 亚洲第一级黄色片| 91久久精品国产91久久| 国产噜噜噜噜久久久久久久久| 日韩欧美亚洲成人| 欧美激情极品视频| 亚洲天堂久久av| 亚洲男人天堂视频| 国产精品com| 国产精品免费一区豆花| 亚洲精品国产电影| 亚洲缚视频在线观看| 亚洲成人激情在线观看| 色综合导航网站| 中文字幕少妇一区二区三区| 精品日本美女福利在线观看| 亚洲欧美另类自拍| 成人免费大片黄在线播放| 一区二区三区回区在观看免费视频| 九九久久久久久久久激情| 蜜月aⅴ免费一区二区三区| www.欧美三级电影.com| 4438全国亚洲精品在线观看视频| 久久色精品视频| 欧美性精品220| 亚洲**2019国产| 91久久综合亚洲鲁鲁五月天| 国产精品69av| 久久久久久国产精品久久| 国产精品视频区1| 欧美性xxxx在线播放| 91精品国产91久久久久久不卡| 国产人妖伪娘一区91| 在线色欧美三级视频| 91高清免费视频| 日韩精品电影网| 国产精品av电影| 红桃视频成人在线观看| 日本中文字幕成人| 18性欧美xxxⅹ性满足| 国产成人免费91av在线| 亚洲美女福利视频网站| 91免费的视频在线播放| 国产视频精品久久久| 成人中心免费视频| 国产精品男女猛烈高潮激情| 8x海外华人永久免费日韩内陆视频| 欧美激情视频在线免费观看 欧美视频免费一| 国产成+人+综合+亚洲欧洲| 久久夜色精品亚洲噜噜国产mv| 亚洲乱码国产乱码精品精| 亚洲乱码国产乱码精品精天堂| 九九视频直播综合网| 日韩女优人人人人射在线视频| 欧美在线视频观看免费网站| 26uuu亚洲国产精品| 久久久久久久久久久网站| 久久久国产精彩视频美女艺术照福利| 精品久久久久久久久久| 亚洲精品日韩丝袜精品| 精品少妇v888av| 欧美成aaa人片在线观看蜜臀| 日韩av电影在线播放| 成人欧美一区二区三区黑人| 欧美劲爆第一页| 成人欧美一区二区三区黑人孕妇| 国产不卡视频在线| 国产精品视频自在线| 欧美激情2020午夜免费观看| 裸体女人亚洲精品一区| 日韩欧美在线观看视频| 国产成人小视频在线观看| 国产精品久久久久久久一区探花| 亚洲最新av在线网站|