事件总线

133 阅读1分钟

前言

在平常使用 vue 做开发时,我们都会通过一些方式来进行数据的传输,例如父子、爷孙、事件总线等,而 事件总线 是不依赖与组件间关系的相互传递数据的一种模式。

事件总线 (EventBus)

作为多个模块间的通信方式,相当于一个任务事务所平台,接受向该平台注册任务事件或领取任务事件,起到一个发布订阅者模式,所以组件间都可以通过这个平台来通知其他组件 起到数据传输的桥梁,达到了通信的作用。

原理 本质上是采用了发布-订阅的设计模式

发布-订阅者

发布者(Publisher):发出事件(Event)
订阅者(Subscriber):订阅事件(Event),并且会进行响应(Handler)

在A,B,C模块中 `A``B``C` 订阅了一个事件 `eventName`,在D模块中发布了`eventName`这个事件,那么事件总线就会负责通知所有订阅者,它们都能收到这个通知消息,以及传递过来的参数。

第三方库使用

1、Vue2默认是带有事件总线的功能
main.js中 引入 let Bus = new Vue();

2、Vue3中推荐一些第三方库,比如mitt;
...

自定义组件

class eventBus {
  constructor() {
    this.eventBus = {}
  }

  on(eventName, eventCallback, thisArg) {
    let handlers = this.eventBus[eventName]
    if (!handlers) {
      handlers = []
      this.eventBus[eventName] = handlers
    }
    handlers.push({
      eventCallback,
      thisArg
    })
  }

  off(eventName, eventCallback) {
    const handlers = this.eventBus[eventName]
    if (!handlers) return
    const newHandlers = [...handlers]
    for (let i = 0; i < newHandlers.length; i++) {
      const handler = newHandlers[i]
      if (handler.eventCallback === eventCallback) {
        const index = handlers.indexOf(handler)
        handlers.splice(index, 1)
      }
    }
  }

  emit(eventName, ...payload) {
    const handlers = this.eventBus[eventName]
    if (!handlers) return
    handlers.forEach(handler => {
      handler.eventCallback.apply(handler.thisArg, payload)
    })
  }
}