# vue bus非父子组件通信

实例化一个空Vue实例,利用Vue上事件监听与触发的功能,实现各组件之间通信。

使用vue-bus有两点需要注意: 第一是$bus.on应该在created钩子内使用,如果在mounted使用,它可能接收不到其他组件来自created钩子内发出的事件。

第二点是使用了$bus.on在beforeDestory钩子里应该需要使用$bus.off解除,因为组件销毁后,就没有必要把监听的句柄存储在vue-bus里面了。

  • 例如简单实现

let Bus = new Vue();
//A组件中监听事件拿到数据做对应地逻辑处理
Bus.$on('test' data => {
//这里监听拿到的数据,然后做对应处理
})
//B组件中触发事件并传递参数
Bus.$emit('test',params);
let Bus = new Vue();
//A组件中监听事件拿到数据做对应地逻辑处理
Bus.$on('test',data => {
    // 拿到数据逻辑处理
}});

  • 稍微封装一下 一般是将Bus抽离出来
Bus.js
import Vue from 'vue'
const Bus = new Vue()
export default Bus

//在Vue实例化时挂在到data属性上去
import Vue from 'vue'
const Bus = new Vue()

var app= new Vue({
    el:'#app',
   data:{
    Bus
    }  
})

在子组件中通过this.$root.Bus.$on(),this.$root.Bus.$emit()来调用

  • 进一步封装
vue-bus.js
const install = (Vue) => {
    Vue.prototype.$bus = new Vue({
        methods: {
            emit(event,...args){
                this.$emit(event,...args);
            },
            on(event,callback){
                this.$on(event,callback);
            },
            off(event,callback){
                this.$off(event,callback);
            }
        }
    });
};
export default install;



然后在main.js

import VueBus from './assets/vue-bus'
Vue.use(VueBus);

然后在组件中,可以使用$emit, $on, $off 分别来分发、监听、取消监听事件: 分发事件的组件

// ...
methods: {
 todo: function () {
 this.$bus.$emit('todoSth', params); //params是传递的参数
 //...
 }
}

监听的组件

// ...
created() {
 this.$bus.$on('todoSth', (params) => { //获取传递的参数并进行操作
  //todo something
 })
},
// 最好在组件销毁前
// 清除事件监听
beforeDestroy () {
 this.$bus.$off('todoSth');
},

如果需要监听多个组件,只需要更改 bus 的 eventName:

// ...
created() {
 this.$bus.$on('firstTodo', this.firstTodo);
 this.$bus.$on('secondTodo', this.secondTodo);
},
// 清除事件监听
beforeDestroy () {
 this.$bus.$off('firstTodo', this.firstTodo);
 this.$bus.$off('secondTodo', this.secondTodo);
},

Last Updated: 3/16/2020, 12:11:08 AM