全局事件总线的原理是基于发布-订阅模式(Publish-Subscribe Pattern),该模式是一种软件设计模式。
用于在一个应用程序中进行组件之间的通信。它通过在应用程序的不同部分中触发和监听事件来实现组件之间的解耦。原生JS可以通过创建一个简单的全局事件总线来实现这种通信机制。以下是全局事件总线的基本原理与思路:
-
发布-订阅模式: 该模式涉及两个主要角色 - 发布者(Publisher)和订阅者(Subscriber)。发布者负责发布(触发)事件,而订阅者则通过订阅事件来接收通知。
-
事件对象: 通常,一个事件是一个包含相关信息的对象。当发布者触发事件时,它可以传递一些数据给所有订阅者。
-
事件总线对象: 在全局事件总线中,通常会有一个中央的事件总线对象,用于管理所有的事件。这个对象包含一个事件注册表,用于存储不同类型事件的订阅者列表。
-
订阅事件: 组件或模块可以通过订阅事件来表达对某一类型事件的关注。订阅者向事件总线注册一个回调函数,该回调函数将在相应事件触发时执行。
-
触发事件: 发布者通过事件总线触发事件,并传递相关数据。事件总线负责找到相应类型的订阅者列表,并依次调用它们的回调函数。
-
解耦性: 这种模式有助于降低组件之间的耦合性。发布者和订阅者无需直接引用对方,它们只需要通过事件总线进行通信,使得系统更加灵活和易于维护。
以下是一个简单的原生JS实现全局事件总线的示例:
// 创建全局事件总线对象
const eventBus = {
listeners: {},
// 添加事件监听器
on: function (eventName, callback) {
if (!this.listeners[eventName]) {
this.listeners[eventName] = [];
}
this.listeners[eventName].push(callback);
},
// 触发事件
emit: function (eventName, data) {
const listeners = this.listeners[eventName];
if (listeners) {
listeners.forEach(callback => {
callback(data);
});
}
},
// 移除事件监听器
off: function (eventName, callback) {
const listeners = this.listeners[eventName];
if (listeners) {
this.listeners[eventName] = listeners.filter(listener => listener !== callback);
}
}
};
使用示例:
// 订阅事件
eventBus.on('customEvent', data => {
console.log('Event received:', data);
});
// 触发事件
eventBus.emit('customEvent', { message: 'Hello, EventBus!' });
// 取消订阅事件
const callback = data => {
console.log('Another listener:', data);
};
eventBus.on('customEvent', callback);
eventBus.off('customEvent', callback);
全局事件总线的意义在于它提供了一种简单而灵活的机制,允许不同部分的代码进行通信,而无需直接引用或依赖彼此。这种解耦有助于提高代码的可维护性和可扩展性,因为组件可以独立开发和测试,而不需要担心与其他组件的直接耦合关系。此外,全局事件总线还可以用于实现跨组件的状态管理和消息传递,从而简化复杂应用程序的开发和维护。
或者
const EventBus = {};
EventBus.on = function(eventName,callback){
if(!EventBus[eventName]){
EventBus[eventName] = [];
}
EventBus[eventName].push(callback)
}
EventBus.emit = function(eventName,data={}){
if(EventBus[eventName]){
EventBus[eventName].forEach(element => {
element(data)
});
}
}
EventBus.off = function(eventName,callback){
if(EventBus[eventName]){
EventBus[eventName] = EventBus[eventName].filter(item=>item !== callback)
}
}
function fun(data=1){
console.log(data);
}
EventBus.on("one",fun)
EventBus.on("two",fun)
EventBus.emit('one',{name:'niupeng'})
EventBus.off('two',fun)
EventBus.emit('two',{name:'niupeng-two'})
// console.log(EventBus);
通过上述实现,任何组件都可以通过eventBus.on
订阅事件,通过eventBus.emit
触发事件,实现组件之间的松散耦合通信。这种思路使得代码更具可扩展性和可维护性,同时提高了系统的灵活性。