详解vue2父组件传递props异步数据到子组件的问题

网友投稿 479 2023-05-03


详解vue2父组件传递props异步数据到子组件的问题

测试环境:vue v2.3.3, vue v2.3.1

案例一

父组件parent.vue

// asyncData为异步获取的数据,想传递给子组件使用

父组件

子组件child.vue

子组件{{childData}}

上面按照这里的解析,子组件的html中的{{childData}}的值会随着父组件的值而改变,但是created里面的却不会发生改变(生命周期问题)

案例二

parent.vue

父组件

child.vue

子组件

{{childObject.items[0]}}

created里面的却不会发生改变, 子组件的html中的{{{childObject.items[0]}}的值虽然会随着父组件的值而改变,但是过程中会报错

// 首先传过来的是空,然后在异步刷新值,也开始时候childObject.items[0]等同于''.item[0]这样的操作,所以就会报下面的错

vue.esm.js?8910:434 [Vue warn]: Error in render function: "Typhttp://eError: Cannot read property '0' of undefined"

针对二的解决方法:

使用v-if可以解决报错问题,和created为空问题

// parent.vue

父组件

child.vue

子组件

{{childObject.items[0]}}

子组件使用watch来监听父组件改变的prop,使用methods来代替created

parent.vue

父组件

child.vue

子组件

{{test}}

子组件watch computed data 相结合,有点麻烦

parent.vue

父组件

child.vue

子组件

{{test}}

使用emit,on,bus相结合

parent.vue

父组件

child.vue

子组件

{{test}}

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

使用prop default来解决{{childObject.items[0]}}

parent.vue

父组件

child.vue

子组件

{{childObject.items[0]}}

在说用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 = false

import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({

modules: {

index

}

})

/* eslint-disable no-new */

new Vue({

el: '#app',

store,

router,

template: '',

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

父组件

child.vue

子组件

{{$store.state.index.asyncData.items[0]}}

http://

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

父组件

child.vue

子组件

{{item0}}

{{item}}

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

子组件

{{item0}}

{{item}}

不过根据以上的案例,得出来一个问题就是异步更新值的问题,就是说开始的时候有个默认值,这个默认值会被异步数据改变,比如说这个异步数据返回的object,如果你用props的方式去传递这个数据,其实第一次传递的空值,第二次传递的是更新后的值,所以就出现{{childObject.items[0]}}类似这种取不到值的问题,既然说第一次是空值,它会这样处理''.items[0],那么我们是不是可以在html判断这个是不是空(或者在computed来判断是否为默认值),所以把案例二的child.vue

{{childObject != '' ? childObject.items[0]: ''}}

这样是可以通过不报错的,XYPvr就是created是空值,猜想上面vuex去stroe也可以也可以这样做


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:spring boot整合spring
下一篇:serialVersionUID作用全面解析
相关文章

 发表评论

暂时没有评论,来抢沙发吧~