JS高级 之 eventBus 事件总线

JS高级 之 eventBus 事件总线_第1张图片

目录

一、概念

二、手写

1. 代码

2. 栗子

三、Vue2 中

1. 在 main.js 中注册

2. 在某组件发射事件

3. 在某组件监听事件         

4. 移除事件 

四、Vue3 中

1. 安装

2. 封装一下

3. 发射事件 

4. 监听事件

5. 取消事件


一、概念

事件总线也是一种通信方式,只不过它的功能比较强大,不在局限于父传子或兄弟组件之间通信,它可以跨组件通信,通过事件总线传递的值,不管哪个组件都可以获取到

 

总而言之,可以在各个模块中通信并且传递数据

事件总线属于一种观察者模式,其中包括三个角色 : 

  • 发布者(Publisher):发出事件(Event)
  • 订阅者(Subscriber):订阅事件(Event),并且会进行响应(Handler)
  • 事件总线(EventBus):无论是发布者还是订阅者都是通过事件总线作为中台的

二、手写

1. 代码

class StarEventBus {
  constructor() {
    // 事件名称 和 方法的映射关系
    this.eventMap = {};
  }
  /**
   *  监听
   *  因为可能有相同的名字监听,但是回调函数不一样
   *  所以使用数组存储
   */
  on(eventName, fn) {
    if (!this.eventMap[eventName]) {
      this.eventMap[eventName] = [];
    }
    this.eventMap[eventName].push(fn);
  }
  /**
   * 发射事件
   * 一发射就自动调用方法
   */
  emit(eventName, ...args) {
    if (!this.eventMap[eventName]) return;
    this.eventMap[eventName].forEach((fn) => {
      fn(...args);
    });
  }
  /**
   * 删除事件
   * 删除事件名和其对应的函数
   */
  off(eventName, fn) {
    if (!this.eventMap[eventName]) return;

    // 可能拥有相同的事件名和相同的函数,所以循环删除
    this.eventMap[eventName].forEach((itemFn, index) => {
      if (itemFn === fn) {
        // 使其位置还在,不过是为空
        delete this.eventMap[eventName][index];
      }
    });
    // 过滤空的值
    this.eventMap[eventName] = this.eventMap[eventName].filter((item) => item);

    // 如果eventFns已经清空了
    if (this.eventMap[eventName].length === 0) {
      delete this.eventMap[eventName];
    }
  }
  /**
   * 清空事件名对应的事件函数数组
   */
  clear(eventName) {
    if (!this.eventMap[eventName]) return;
    delete this.eventMap[eventName];
  }
  /**
   * 清空所有事件
   */
  clearAll() {
    this.eventMap = {};
  }
}

2. 栗子

// 1. 创建对象
const eventBus = new StarEventBus();

// 2. 监听方法
eventBus.on('btnClick', () => {
  console.log('俺被惦记了');
});

const btnClick = () => {
  console.log('俺也被惦记了');
};
eventBus.on('btnClick', btnClick);

setTimeout(() => {
  // 4. 删除方法
  eventBus.off('btnClick', btnClick);
}, 3000);

const btnDom = document.querySelector('button');
btnDom.onclick = function () {
  console.log('btn 点击');
  // 3. 发射方法
  eventBus.emit('btnClick');
};

三、Vue2 中

Vue2默认是带有事件总线的功能,因为vue实例自带了以下方法

1. 在 main.js 中注册

// 在入口 main.js 中,创建一个 bus 总线,这样全局都可以使用
Vue.prototype.$bus = new Vue()

2. 在某组件发射事件


 


4. 监听事件




5. 取消事件

// 取消所有的事件监听
emitter.all.clear()

// 取消指定事件监听,方法要使用同一个 如 : sonEmit. 
function onFoo(){}
emitter.on('sonEmit', onFoo)
emitter.off('sonEmit', onFoo)

你可能感兴趣的:(JS高级,javascript,开发语言,ecmascript,事件总线,eventBus)