中央事件总线bus

140 阅读1分钟

自定义事件的语法

在Vue实例对象的原型上有绑定事件和触发事件以及解绑事件的三个功能,所以VueComponent构造函数创建的组件也有以上三个功能。

1.给x组件绑定a事件:x.$on("a事件",监听器函数)
2.触发x组件的a事件: x.$emit("a事件",参数...)
3.给x组件解绑a事件:x.$off("a事件",监听器函数)

中央事件总线

通过创建一个新的vm对象,新的vm对象不会用于渲染页面只负责专门统一注册事件,供所有组件共同操作,达到所有组件随意隔代传值的效果,兄弟组件也可以直接通过新的vm对象进行数据交互。需要传数据的组件就触发事件,接收数据的组件就绑定事件,绑定事件和触发事件的组件必须是同一个。所以在新的vm对象上绑定一个bus属性,属性名可以任意取,bus更见明知意,用$只是表示绑定在Vue实例的原型对象上。

在main.js文件中给Vue原型对象上添加一个$bus属性,属性值就是new Vue创建一个Vue实例,其中也可以传入一个对象有data属性,methods方法等,就把触发事件和绑定事件的函数封装在函数,还可以写一些逻辑判断,判断是否事件是否绑定过等。

//main.js
Vue.prototype.$bus=new Vue({
  data:{
    eventarr:[]
  },
  methods:{
    emit(event, ...args) {
      if(this.eventarr.includes(event)){
        throw '事件名已经注册过'
      }else{
        this.eventarr.push(event);
        this.$emit(event, ...args);
      }
    },
    on(event, callback) {
      this.$on(event, callback);
    },
    off(event, callback) {
      for(let i=0;i<this.eventarr.length;i++){
        if(this.eventarr[i]==event){
          // 解绑之后删除事件
          this.eventarr.splice(i,1);
        }
      }
      this.$off(event, callback);
    }
  }
});
new Vue({
  render: h => h(App)
}).$mount('#app')

ps:需要先在原型对象添加属性,创建实例对象之后才可以访问在原型对象添加的属性

任意组件的业务中都可以通过调用来绑定事件,触发事件并传值和销毁事件

//组件文件中:
this.$bus.on(event,callback) 
this.$bus.off(event,callback) 
this.$bus.emit(event, ...args)

image.png