本文同步刊載於Andy's Blog
昨天介紹了props.sync方法,今天我們來介紹另外一種元件的溝通方式。event bus
(老司機XD)。
開始前,我們回憶一下,props、emit的傳遞方式如下圖:
圖片來源:五倍紅寶石
我們可以發現資料與資料間的溝通方式,是樹狀傳遞
,這代表什麼呢?假設我今天要跟旁邊的component(元件)進行溝通,那我們是不是要先把資料傳到最上層父元素後,再依序傳下來呢?光想就覺得好麻煩,這什麼鬼方法。
引用Kuro老師譬喻:
子孫元件要溝通講秘密,卻連上層阿公都知道XD
沒錯,若遇到不是上下階層關係的元件,我們在傳遞資料時候的確相當麻煩,因此這時候就需要老司機來幫助我們解決這個問題摟~
目的:幫助我們將元件間的溝通方式由樹狀結構,轉變成網狀模式。
寫法:
Step1. 新增一個Vue實體var bus = new Vue()
Step2. 透過向bus發送註冊事件($emit),與訂閱事件($on)來完成元件與元件的溝通
圖片來源:五倍紅寶石課程
範例:練習連結
HTML部分
<div id="app">
<custom-one></custom-one>
<hr>
<custom-two></custom-two>
</div>
JavaScript部分
var bus = new Vue();
//元件一
Vue.component('custom-one',{
template:`<div>
<input type="text" v-model="msg">
<button @click="update">update</button>
</div>`,
methods:{
update(){
bus.$emit('receive',this.msg); //向bus發送receive事件
}
},
data(){
return{
msg:'',
}
}
})
//元件二
Vue.component('custom-two',{
template:`
<div>
{{msg}}
</div>
`,
created() {
var self= this;
bus.$on('receive',function(newMsg){ //向bus訂閱事件
console.log(self);
self.msg =newMsg
})
},
beforeDestroy() {
bus.$off('receive') //記得要手動清除監聽事件,不然Vue不會自動幫我們取消喔
},
data(){
return{
msg:''
}
}
})
var app = new Vue({
el: '#app'
});
1.使用event bus時,要注意事件名稱的命名。避免造成事件重複訂閱!
2.監聽完事件後必須手動清除事件監聽!
很重要要講三遍
3.元件與元件之間若為父子關係,應該使用props、emit方法,避免濫用