Vue2.x中兄弟組件之間傳值可以使用Vuex來(lái)達(dá)到目的,如果項(xiàng)目中不需要類(lèi)似Vuex這樣的庫(kù)來(lái)處理組件之間的數(shù)據(jù)通信千康,就可以考慮Vue中的事件總線 ,即 EventBus來(lái)通信。
vue2.x中實(shí)現(xiàn)實(shí)現(xiàn)EventBus
// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
或者
// main.js
Vue.prototype.$EventBus = new Vue()
因?yàn)関ue實(shí)例中提供了$on梭稚、$emit等方法所以只需要?jiǎng)?chuàng)建一個(gè)空的vue實(shí)例,在組件中通過(guò)$on()注冊(cè)事件絮吵,在另外一個(gè)組件中通過(guò)$emit()去執(zhí)行對(duì)應(yīng)的事件并且可以傳參來(lái)達(dá)到組件之間的通訊弧烤。
實(shí)現(xiàn)一個(gè)簡(jiǎn)單的EventBus
const eventBus = () => {
/* 訂閱器 */
subs = new Map();
return {
subs,
/**
* 注冊(cè)事件
* @param {string} type 事件類(lèi)型
* @param {Function} callback 回調(diào)函數(shù)
*/
$on (type, callback) {
const sub = subs.get(type);
const isEmpty = sub && sub.push(callback);
if (!isEmpty) {
subs.set(type, [callback]);
}
},
/**
* 觸發(fā)事件
* @param {string} type 事件類(lèi)型
* @param {Any} payload 傳遞的參數(shù)
*/
$emit (type, ...payload) {
(subs.get(type) || []).forEach(fn => { fn(...payload) });
(subs.get('*') || []).forEach(fn => { fn(...payload) }); /* 所有事件類(lèi)型都執(zhí)行 */
},
/**
* 注銷(xiāo)事件
* @param {string} type 事件類(lèi)型
* @param {Function} callback 回調(diào)函數(shù)
*/
$off (type, callback) {
const sub = subs.get(type);
if (sub) {
sub.splice(sub.indexOf(callback) >>> 0, 1);
}
}
}
}
module.exports = eventBus
subs訂閱器可以使用對(duì)象或者來(lái)Map來(lái)實(shí)現(xiàn),Map自帶clear方法可以清除所有注冊(cè)的事件
subs = new Map();
其原理就是以事件類(lèi)型type作為Map的key值蹬敲,以數(shù)組作為value值暇昂,數(shù)組里面裝的是一個(gè)個(gè)執(zhí)行的回調(diào)函數(shù),通過(guò)$on注冊(cè)的事件如果是相同的type就會(huì)被push同一個(gè)數(shù)組當(dāng)中伴嗡,調(diào)用$emit的時(shí)候找到對(duì)應(yīng)的type循環(huán)數(shù)組執(zhí)行里面所有的回調(diào)函數(shù)急波。
使用
const eventBus = require('./eventBus')
const emitter = eventBus()
// 注冊(cè)change事件
emitter.$on('change', (...payload) => {
console.log('change', ...payload)
})
// 調(diào)用所有事件都會(huì)執(zhí)行這個(gè)方法
emitter.$on('*', (...payload) => {
console.log('all', ...payload)
})
//觸發(fā)change事件
emitter.$emit('change', '參數(shù)1', '參數(shù)2')
運(yùn)行結(jié)果
可以使用Map自帶的clear清空EventBus
emitter.subs.clear() // 清空EventBus