Detailed explanation of event bus eventBus

event bus

Provide an event bus to give other components or modules the right to monitor and modify data. The specific things it does can include the following:

  1. Provide an interface for monitoring an event
  2. Provides an interface to cancel monitoring
  3. Interface that triggers events (can pass data)
  4. After the event is triggered, the listener will be automatically notified

The following is an introduction to how to use code to achieve the effect of the event bus.

First, create a new file globally eventBus.js. This file is at main.jsthe parallel level. We hope that it will export an event bus. It is actually an object, which contains the relevant configuration content of the event bus and contains method interfaces.

/*
* 事件总线
* 具体完成上述的四个功能(其中第四个功能是通过前三个完成的)
* 导出对象,内部包含一些方法,供外部调用
*/
/*
   给一个全局的数组,每次有添加监听事件的时候,就往内部添加一个对象,其属性名是事件名,属性值是一个数组,
   里边是对此事件进行监听的处理函数(因为可能有很多组件或JS模块对该事件进行监听),这里可以使用new Set()
   集合进行自动的去重操作!
   [
   	{'event1': [ handler1, handler2 ]},
   	{'event2': [ handler1 ]},
   ]
*/
const $listeners = [];
export default {
    
    
    // 开启某个事件的监听
    $on(eventName, handler){
    
    
        if(!$listeners[eventName]){
    
    
            $listeners[eventName] = new Set();
        }
        $listeners[eventName].add(handler);
    },
    // 取消某个事件的监听
    $off(eventName, handler){
    
    
        if(!$listeners[eventName]){
    
    
            return;
        }
        $listeners[eventName].delete(handler);
    },
    // 触发某个事件(可以传参),通过剩余参数接受
    $emit(eventName, ...args){
    
    
        if(!listeners[eventName]){
    
    
            return;
        }
        listeners[eventName].forEach((handler)=>{
    
    
            handler(...args);
        });
	}
}

After the module is completed, we go to main.jsthe file to test. The test code is as follows

// 测试事件总线接口
import eventBus from "./eventBus";

function handler1(data){
    
    
  console.log("handler1", data);
}

function handler2(data){
    
    
  console.log("handler2", data);
}

eventBus.$on("event1", handler1);
eventBus.$on("event1", handler2);
eventBus.$on("event2", handler1);

window.eventBus = eventBus;
window.handler1 = handler1;
window.handler2 = handler2;

Briefly interpreted, this code is equivalent to adding two objects to the event bus.

The first one is about events event1, which contains two processing functions handler1and handler2are stored in an array and assigned to the event event1as the attribute value of the event.

The first one is about events event2, which contains a processing function handler1, which is stored in an array and assigned to the event event2as the attribute value of the event.

The last part is to register the event bus globally to facilitate subsequent debugging on the console.

As shown in the figure, when you run the following code, you can see that when an event1event is thrown using the event bus, two processing functions are run at the same time, and the parameter data is substituted into the processing functions respectively.
Insert image description here

When an event is thrown using the event bus event2, the handler function is run handler1and the parameters are 456substituted into the handler function.

Insert image description here

Let's test the function to cancel event monitoring. You can see that after running, when the event bus throws an event eventBus.$off("event1", handler1)here , only the processing function will be run, which means that the event processing function collection will be deleted. , but has no effect on the event handler function of the event.event1handler2handler1event1event2

Insert image description here

At this point, it shows that the function of the above event bus has been completed and can successfully achieve the results we expected.

But why are the instance member attributes and methods so close to each other used here ? That's because in general development, a new instance is often used $emitto achieve the above effects, because an instance has several of the above methods built-in.$onvuevuevue

Therefore, we eventBus.jscan write as follows in the event bus module

import Vue from "vue";
export default new Vue({
    
    });

That's fine, because the , , method vueis built into the component instance object , so you can directly call the original test code unchanged.$on$off$emit

Guess you like

Origin blog.csdn.net/facial_123/article/details/126814140