Vue2.x中兄弟组件之间传值能够使用Vuex来达到目的,若是项目中不须要相似Vuex这样的库来处理组件之间的数据通讯,就能够考虑Vue中的事件总线 ,即 EventBus来通讯。vue
// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
或者
// main.js
Vue.prototype.$EventBus = new Vue()
复制代码
由于vue实例中提供了$on、$emit等方法因此只须要建立一个空的vue实例,在组件中经过$on()注册事件,在另一个组件中经过$emit()去执行对应的事件而且能够传参来达到组件之间的通信。web
const eventBus = () => {
/* 订阅器 */
subs = new Map();
return {
subs,
/** * 注册事件 * @param {string} type 事件类型 * @param {Function} callback 回调函数 */
$on (type, callback) {
const sub = subs.get(type);
const isEmpty = sub && sub.push(callback);
if (!isEmpty) {
subs.set(type, [callback]);
}
},
/** * 触发事件 * @param {string} type 事件类型 * @param {Any} payload 传递的参数 */
$emit (type, ...payload) {
(subs.get(type) || []).forEach(fn => { fn(...payload) });
(subs.get('*') || []).forEach(fn => { fn(...payload) }); /* 全部事件类型都执行 */
},
/** * 注销事件 * @param {string} type 事件类型 * @param {Function} callback 回调函数 */
$off (type, callback) {
const sub = subs.get(type);
if (sub) {
sub.splice(sub.indexOf(callback) >>> 0, 1);
}
}
}
}
module.exports = eventBus
复制代码
subs订阅器能够使用对象或者来Map来实现,Map自带clear方法能够清除全部注册的事件数组
subs = new Map();
复制代码
其原理就是以事件类型type做为Map的key值,以数组做为value值,数组里面装的是一个个执行的回调函数,经过$on注册的事件若是是相同的type就会被push同一个数组当中,调用$emit的时候找到对应的type循环数组执行里面全部的回调函数。markdown
const eventBus = require('./eventBus')
const emitter = eventBus()
// 注册change事件
emitter.$on('change', (...payload) => {
console.log('change', ...payload)
})
// 调用全部事件都会执行这个方法
emitter.$on('*', (...payload) => {
console.log('all', ...payload)
})
//触发change事件
emitter.$emit('change', '参数1', '参数2')
复制代码
能够使用Map自带的clear清空EventBusapp
emitter.subs.clear() // 清空EventBus
复制代码