前面提到了父子元件透過emit & prop進行參數傳遞,當樹狀結構逐漸複雜時,在傳遞上複雜度也越來越高。
ex: 兩個子元件互相傳遞時(子元件1 -> 子元件2)
子元件1 -> 父元件1 -> 子元件2
避免複雜的跨組溝通,可使用vuex
以及Event Bus
進行處理。
Event Bus 四個方法:
$on: 監聽
$once: 監聽一次
$off: 取消監聽
$emit: 傳遞事件
最好於created
即進行監聽,beforeDestroy
進行取消。
實作結構圖
對Event Bus 而言
main.js
引入bus
Vue.prototype.$bus = new Vue();
子元件 Event
HTML
<h1>Event 計數器: {{ count }}</h1>
<button @click="addCount">Event計數鈕</button>
Data (三個組件皆預設: 0)
count: 0
定義方法addCount (count+1 & 傳遞事件、值)
addCount: function () {
// 透過emit傳遞
this.count += 1;
this.$bus.$emit("add-count", this.count);
}
父元件 App
HTML
<h1>App 計數器: {{ count }}</h1>
<!-- 引入子元件 -->
<Event/>
<Bus/>
生命週期 created
註冊監聽
created() {
// 註冊監聽 $once 監聽一次
this.$bus.$once("add-count", val => {
this.count = val;
});
},
生命週期 beforeDestroy
取消監聽
beforeDestroy() {
// 監聽需於銷毀前取消
this.$bus.$off("add-count");
},
子元件 Bus
HTML
<h1>Bus計數器: {{ count }}</h1>
生命週期 created 註冊監聽
created() {
// 註冊監聽 $on 持續監聽
this.$bus.$on("add-count", val => {
this.count = val;
});
},
生命週期 beforeDestroy
與父元件相同
Event Bus 可視為對全域
發出事件與資料,但不是用於較為複雜的系統,較為複雜、龐大的系統則透過vuex
進行全域控制較佳。
以上範例為vue 2,vue 3已移除Event Bus相關用法,透過Mitt
進行替代。
有錯誤請不吝指教!
參考資料
https://vuejs.org/v2/guide
https://medium.com/itsems-frontend/vue-event-bus-15b76f27aeb9
https://ithelp.ithome.com.tw/articles/10242193
感謝各路大神