Vue元件通訊中eventBus的使用

CodeMan發表於2018-03-09

在vue1.0中,元件之間的通訊主要通過vm.$dispatch沿著父鏈向上傳播和用vm.$broadcast向下廣播來實現。然而在vue2.0中,已經廢除了這種用法。

vuex加入後,對元件之間的通訊有了更加清晰的操作,對於中大型的專案來說,一開始就把vuex的使用計劃在內是明智的選擇。

然而在一些小型的專案,或者說像我這樣寫到一半才發現vue2.0用不了$.broadcast和$dispatch的人來說,就需要一個比較便捷的解決方法。那麼,eventBus的作用就體現出來了。

主要是現實途徑是在要相互通訊的兄弟元件之中,都引入一個新的vue例項,然後通過分別呼叫這個例項的事件觸發和監聽來實現通訊和引數傳遞。

這裡來看一個簡單的例子:

比如,我們這裡有三個元件,main.vue、click.vue、show.vue。click和show是父元件main下的兄弟元件,而且click是通過v-for在父元件中遍歷在了多個列表項中。這裡要實現,click元件中觸發點選事件後,由show元件將點選的是哪個dom元素console出來。

首先,我們給click元件新增點選事件

<div class="click" @click.stop.prevent="doClick($event)"></div>  

想要在doClick()方法中,實現對show元件的通訊,我們需要新建一個js檔案,來建立出我們的eventBus,我們把它命名為bus.js

import Vue from 'vue';  
export default new Vue(); 

這樣我們就建立了一個新的vue例項。接下來我們在click元件和show元件中import它。

import Bus from 'common/js/bus.js';  

接下來,我們在doClick方法中,來觸發一個事件:

methods: {  
   addCart(event) {  
   Bus.$emit('getTarget', event.target);   
   }  
}  

這裡我們在click元件中每次點選,都會在bus中觸發這個名為'getTarget'的事件,並將點選事件的event.target順著事件傳遞出去。

接著,我們要在show元件中的created()鉤子中呼叫bus監聽這個事件,並接收引數:

created() {  
        Bus.$on('getTarget', target => {  
            console.log(target);  
        });  
}  

這樣,在每次click元件的點選事件中,就會把event.target傳遞到show中,並console出來。

所以eventBus的使用還是非常便捷的,但是如果是中大型專案,通訊比較複雜,還是建議大家直接使用vuex。

來看一個實際例子:

我們建立了一個selection.vue的下拉框元件,在layout.vue元件中使用了selection.vue元件,我們要實現點選layout.vue元件頁面的任意一處(除下拉框元件本身外),都可以將下拉框收起來。首先,新建了一個eventBus.js檔案,在裡面新建了一個vue的例項賦值給const eventBus,在selection.vue和layout.vue中分別import eventBus from '../../eventBus'和import eventBus from '../eventBus',則eventBus對於selection.vue和layout.vue就是一個全域性的vue例項物件,然後通過分別呼叫eventBus這個例項的事件觸發$emit和事件監聽$on來實現通訊和引數傳遞。圖6,是為了在一個頁面中,把selection.vue使用了至少兩次,則我們點選任意一個selection.vue的同時,要把其它的selection.vue給收起來,如圖7。

圖1:
clipboard.png

圖2:
clipboard.png

圖3:
clipboard.png

圖4:
clipboard.png

圖5:
clipboard.png

圖6:
clipboard.png

圖7:
clipboard.png

相關文章