假设这个组件:
<template>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Example Component</div>
<div class="panel-body">
I'm an example component!
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ message: 'Test 1' },
{ message: 'Test 2' },
{ message: 'Test 3' },
]
}
},
mounted() {
console.log('Component mounted.')
}
}
</script>
这是我的app.js
:
Vue.component('example', require('./components/Example.vue'));
const app = new Vue({
el: '#app'
});
现在,我需要在示例组件中打印所有items
,如下所示:
<ul id="example-2">
<li v-for="(item, index) in items">
@{{ index }} - @{{ item.message }}
</li>
</ul>
它返回以下错误:
[Vue警告]:未在实例上定义属性或方法“items” 但在渲染期间引用。确保声明反应数据 数据选项中的属性。 (找到)
主要问题是:
如何将子组件中的数据传递给Root?
任何帮助都会非常感激。
答案 0 :(得分:4)
您可以通过三种方式进行非父子(直接关系)沟通。
从子组件发出一个事件,然后进一步从接收父级发出值,直到root收到该值。 (不要用这个)
使用event bus,如果您的应用程序规模较小,这就是您正在寻找的答案。
使用vuex,如果您的应用程序更多地使用组件状态/是大规模应用程序,这就是您正在寻找的答案。
示例强>
// assuming your component
import { mapActions } from 'vuex'
export default {
data() {
return {
items: [
{ message: 'Test 1' },
{ message: 'Test 2' },
{ message: 'Test 3' },
]
}
},
mounted() {
console.log('Component mounted.')
this.setItemsToStore(this.items)
},
methods: {
...mapActions({
'setItemsToStore': 'SET_ITEMS_TO_STORE'
})
}
}
然后在main.js中连接vuex
。
import Vue from 'vue'
import { store } from './path/to/store'
import App from './path/to/App'
new Vue({
el: '#app',
store,
template: '<App/>',
components: { App }
})
设置模块化vuex商店,如:
import Vue from 'vue'
import Vuex from 'vuex'
import itemStore from './modules/itemStore'
Vue.use(Vuex)
export const store = new Vuex.Store({
modules: {
itemStore
}
})
最后你的itemStore看起来像:
const state = {
ITEMS: []
}
const getters = {
GET_ITEMS: (state) => {
return state.ITEMS
}
}
const mutations = {
MUTATE_ITEMS: (state, payload) => {
state.ITEMS = payload
}
}
const actions = {
SET_ITEMS_TO_STORE: ({commit}, payload) => {
commit('MUTATE_ITEMS', payload)
}
}
export default {
state,
getters,
mutations,
actions
}
完成此设置后,您的app.js
可以像以下一样使用它:
import { mapGetters } from 'vuex'
const app = new Vue({
el: '#app',
computed: {
...mapGetters({
'items': 'GET_ITEMS'
})
}
});
示例2
//bus.js
export new Vue()
这是一个空的vue实例,将在整个应用程序中使用。
// your assumed component
import eventBus from 'path/to/bus.js'
export default {
data() {
return {
items: [
{ message: 'Test 1' },
{ message: 'Test 2' },
{ message: 'Test 3' },
]
}
},
mounted() {
console.log('Component mounted.')
eventBus.$emit('items-evt', this.items)
}
}
在这里,您只需在安装组件时发出事件。
// app.vue
import eventBus from 'path/to/bus.js'
const app = new Vue({
el: '#app',
data () {
return {
items: []
}
},
created () {
eventBus.$on('items-evt', (items) => {
this.items = items
})
}
});
在应用程序组件创建时刻录。