Vue: EventHub 和 Vue 更配哦

EventHub 是一個非常重要且常用的東西,在不相關元件通訊方面有著很強大的作用。
EventHub
想想如果從最頂層元件傳一個 data 給最底層元件,僅僅使用父子傳遞的方式會變得十分麻煩。
而 EventHub 就是用來解決這個問題的:在需要獲取 data 的元件上設定一個監聽器,每次要傳遞 data 時,那個元件就廣播這個事件並呼叫這些監聽器。我們不難發現 EventHub 的主要功能就兩個: 監聽和廣播 ,當然還有去掉監聽器。而 Vue 剛好給我們提供了這些功能,我們可以使用 Vue 來描述這些功能:
let eventHub = new Vue() // 監聽 eventHub.$on('eventName', (data) => { console.log('Trigger this event and receive ' + data) }) // 廣播 eventHub.$emit('eventName', data) // 去掉監聽 eventHub.$off('eventName')
有沒有感覺很優雅呢?其實本質上這裡就借用了 Vue 的事件監聽功能來完成 EventHub 的。
依賴注入
優雅是優雅,但是這明顯是個全域性變數呀,難道我們要將它放在入口 main.js 裡面初始化麼?還是放在 Vue.prototype
裡直接用 this.eventHub
來使用呢?No no no,Vue 給我們提供了一個更簡潔的寫法:依賴注入。
在頂層元件的 data
裡初始化 EventHub,並使用 provide
對外暴露這個 EventHub。
import Vue from "vue"; export default { name: "App", components: { GrandParent }, data() { return { eventHub: new Vue() }; }, provide() { return { eventHub: this.eventHub }; }, methods: { setRandomValue() { this.eventHub.$emit("update:msg", Math.random() * 100); } } };
然後在需要監聽的元件裡用 inject
注入這個依賴,並在 created
裡新增事件監聽。
export default { inject: ["eventHub"], data() { return { msg: "" }; }, created() { this.eventHub.$on("update:msg", msg => { this.msg = msg; }); } };
最終的結果是在 App 裡修改 msg
,新增監聽事件的子元件都會獲取最新的 msg
,並用其再更新自己的資料或者狀態。