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
複製代碼