vue利用事件總線進行組件通訊

在Vue開發中會遇到大量的組件之間共享數據的情形,針對不一樣的情形,Vue有相對應的解決方案。好比,父組件向子組件傳值可使用props,複雜項目中不一樣模塊之間傳值可使用Vuex。可是,對於一些簡單的項目裏的非父子組件來講,它們一方面不適用props,另外一方面又沒有必要使用Vuex,針對這種情形可使用中央事件總線(Event Bus)來解決問題。vue

主要用到vue的$on和$emit事件,可是這兩個事件必須在同一個vue實例中:
http://jsrun.pro/yfWKp/editwebpack

同一個實例中的$emit事件會被$on監聽捕捉到。使用webpack建立的工程如何共享一個實例呢?咱們能夠建立一個公共實例,將其做爲一個組件引入。web

一、建立中央事件總線
能夠採用多種方式建立事件總線
(1)vue-router

// main.js
import Vue from 'vue';
window.eventBus = new Vue();   // 註冊全局事件對象

// 也能夠修改Vue的原型鏈
Vue.prototype.$bus = new Vue();

(2)做爲js模塊函數

//moduleEvent.js
import Vue from 'vue'
export default new Vue()

// main.js 引入
import moduleEvent from './assets/moduleEvent';
Vue.prototype.$bus = moduleEvent;

(3)做爲vue模塊測試

// moduleEvent.vue
<tempalte>
</template>
<script>
    import Vue from 'vue';
    export default new Vue({
        data () {

        }
    })
</script>

// main.js
import moduleEvent from './assets/moduleEvent';
Vue.prototype.$bus = moduleEvent;

二、使用事件總線this

// moduleA.vue
methods: {
    sendData () {
        // 經過修改Vue原型鏈的方式註冊
        this.$bus.$emit('test', this.dataA);
        // 直接註冊在window上
        // moduleEvent.$emit('test', this.dataA);      
    }
}
// moduleB.vue
methods: {
    getData () {
        // 經過修改Vue原型鏈的方式註冊
        this.$bus.$on('test',  function (data) {
            // handle data code
            // 回調函數的參數data即爲組件A傳遞的值
        });
        // 直接註冊在window上
        // moduleEvent.$on('test',  function (data) {
            // handle data code
            // 回調函數的參數data即爲組件A傳遞的值
        // });      
    }
}

三、單次接收事件或者移除事件Listeners
若是你只想監聽一次該事件。可使用 this.$event.$once(channel: string, callback(payload1, payload2, ...)),事件觸發一次後將移除事件。prototype

若是你想移除自定義事件監聽器,你可使用 this.$event.$off([event, callback]); 來實現。該方法若是沒有提供參數,則移除全部的事件監聽器;若是隻提供事件,則移除該事件全部的監聽器;若是同時提供了事件與回調,則只移除這個回調的監聽器。code

四、路由傳參是否可使用事件總線呢?那樣的話地址欄就不會暴漏id和參數了,我測試了一下發現不行,由於跳轉以前就調用了$emit事件,此時路由還沒加載無法監聽到,只能乖乖的使用vue-router提供的傳參方式。router

相關文章
相關標籤/搜索