vue组件间通讯主要有两种,一种使用事件总线的方式,两种是使用外部状态管理器vuex
事件总线
这种方式的缺点就是不适合开发大型的应用,主要工作原理是使用事件,当应用逐渐长大,开发人员越来越多,定义的事件名称就会可能出现重复,导致应用不能正常工作,通常构建大型应用不建议使用这种通讯方式,适合个人短期的小应用,其优点就是简单,快速构建应用
Bus
创建事件总线中介
import Vue from 'vue'
export default new Vue();
Items
<template>
<div>
<ul>
<li v-for="item in items">{{item.content}}</li>
</ul>
</div>
</template>
<script>
import bus from '../Bus'
export default {
name: 'items',
created() {
//在组件的created钩子创建监听器,items发生变化时更新dom
bus.$on('AddTodo',(item) =>{
this.items.push({content:item});
})
},
methods: {
},
data: () => {
return {items: []}
}
}
</script>
Headers
<template>
<form>
<input type="text" v-model="item"/>
<button v-on:click="addTodo">Add</button>
</form>
</template>
<script>
import bus from '../Bus'
export default {
name: 'headers',
data:() => {
return {
item:''
}
},
methods:{
addTodo(e){
if (this.item){
//当用户点击Add时触发AddTodo
bus.$emit('AddTodo', this.item);
}
e.preventDefault();
}
}
}
</script>
vuex
vuex与事件总线相比,vuex相对较为复杂,带来很多新概念,比如state,action,getters等等,但在大型项目中应该无疑首选的,它让应用可以保持单向数的据流
store/index.js
// @flow
import Vue from 'vue'
import Vuex from 'vuex'
import createLogger from 'vuex/dist/logger'
Vue.use(Vuex); //加载store
export default new Vuex.Store({
plugins: [createLogger()],//非常有用的调试工具,与Redux的log中间件类似
//初始化的状态
state:{
items:[]
},
//用于定义从state中派生出一些状态
getters:{
doneTodosCount(state){
return state.items;
}
},
actions:{
//异步逻辑都应该封装到这里里。
},
mutations:{
//提交 mutation 是更改状态的唯一方法,并且这个过程是同步的
addTodo(state,item){
state.items.push({content:item});
}
}
})
app.js
import Vue from 'vue'
import App from './App'
import store from './store'
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store, //store instanceof vuex
template: '<App/>',
components: { App }
});
Headers
<template>
<form>
<div>
<input type="text" v-model="item"/>
<button @click="addTodo(item)">Add</button>
</div>
</form>
</template>
<script>
import {mapMutations} from 'vuex'
export default {
name: 'headers',
data:() => {
return {
item:'',
keyword:''
}
},
//相当于提交Mutation
/*methods:{
addTodo(){
this.$store.commit('addTodo', this.item)
}
},*/
methods: mapMutations([
'addTodo','search'
]),
}
</script>
items
<template>
<div>
<ul>
<li v-for="item in items">{{item.content}}</li>
</ul>
</div>
</template>
<script>
import {mapState,mapGetters} from 'vuex';
export default {
name: 'items',
/**
* 计算属性,当数据更新时触发组件更新
*/
computed: {
...mapState([
// 映射 this.items 为 store.state.items
'items'
])
}
}
</script>