vue之事件匯流排
阿新 • • 發佈:2021-07-30
1.事件匯流排介紹
在vue中跨越層級的兩個元件進行通訊,若使用props傳值和$emit觸發的方式會十分繁瑣,而事件匯流排的通訊方式更適合跨越層級的元件通訊。
2.事件匯流排原理
事件匯流排可以用一個物件來表示每一個事件 都有一個數組來記錄這個事件的監聽者
{ "event1": [hander1, hander2], "event2": [hander1, hander2, hander3], }
若給某個事件新增監聽者,就把處理函式新增到這個事件對應的陣列中去
若給某個事件取消監聽者,就從這個事件對應的陣列刪除這個處理函式
若要觸發某個事件,就讓這個事件對應的陣列存放的處理函式依次執行
用class模擬一個事件匯流排
// 事件匯流排 class Bus { constructor() { // 用來記錄事件和監聽該事件的陣列 this.listeners = {}; } // 新增指定事件的監聽者 $on(eventName, handler) { this.listeners[eventName].add(handler); } // 取消監聽事件 $off(eventName, handler) { this.listeners[eventName].delete(handler); } // 觸發事件 $emit(eventName, ...args) {this.listeners[eventName].forEach((fn) => fn(...args)); } }
3.事件匯流排的使用
在main.js中,引入事件匯流排
import Vue from 'vue'; import App from './App.vue'; import router from './router/index.js'; // 將事件匯流排作為Vue.prototype的屬性,方便每個元件中通過this.$bus獲取事件匯流排 Vue.prototype.$bus = new Vue({}); new Vue({ el: '#app', render: (h)=> h(App), router, });
直接使用vue例項作為事件匯流排,是因為vue例項上本身就具有這三個方法($on、$emit、$off)
home.vue中觸發事件匯流排的事件
<template> <div> <button @click="handleClick">點選</button> <!-- 使用test-comp元件 --> <test-comp></test-comp> </div> </template> <script> import testComp from './test-comp.vue'; export default { name: 'Home', components: { testComp, }, methods: { handleClick(event) { // 觸發事件匯流排中的事件,並傳引數 this.$bus.$emit('my-click', [1, 2]); }, }, }; </script>
test-comp.vue中訂閱事件匯流排中的事件
<template> <div class="red"></div> </template> <script> export default { mounted() { // 訂閱事件匯流排中的事件,並接受引數(要等home.vue的this.$bus.$emit執行後才能執行) this.$bus.$on('my-click', (msg) => { console.log('接受元件home傳來的引數msg: ', msg); }); }, methods: {}, }; </script>