<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 = 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: '<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