在大多数页面里,组件通常需要相互通信,以完成某些任务或者交互。而在组件的定义里,每个组件是唯一且独立的, 每个组件实例的生成,并无法准确定位到另一个实例。所以我们建立一个全局事件中心,通过进行组件事件的绑定配置,准确的进行组件通信。
实现思路
- 页面初始化完成后,进行事件的初始化。初始化内容如下
- 初始化
emitAll
事件。(任何事件触发都会是广播通知到所有组件。在组件外部会进行拦截是否是有效事件) - 查询所有组件是否有绑定event, 如果存在则注册到事件中心。这里会用组件id作为事件名,所以可以确保唯一
- 组件触发emit事件后,会拿到需要触发的回调函数,进行广播通知。
- 组件外部拦截判断是否是当前组件有效事件。如果有效,那么会传递到组件内部。(当前需要接收事件的组件内部存在处理逻辑,后续会优化提取到外部或者通过配置生效)
逻辑图如下。
- A组件通知事件过滤层
- A的事件过滤层通知EventCenter。
- EventCenter通知到组件ABC的事件过滤层
- AB的事件过滤层发现这个消息是通知C的,选择忽略
- C的事件过滤层层发现是要告诉C的。立马通知C
- C组件C到消息,马上执行!
事件中心代码
事件中心的代码很简单。核心的是,事件的注册时机和监听时期。
注册时机: 组件加载完成后
监听时期:事件绑定后
/**
* 事件注册与响应中心
* 主要处理: 1.注册事件 2.记录事件匹配关系 每个发送者都是接受者 3.统一在此处调度
*/
class eventCenter {
constructor(config) {
// 配置列表
this.config = config || {};
this.events = {};
}
// 注册
register(event, callback) {
if (!this.events[event]) {
this.events[event] = {};
}
// 存储一个对象 每一个key就是一个事件
this.events[event] = callback;
}
// 监听
emit(event, args) {
if (!this.events[event]) {
return;
}
const cbs = this.events[event];
// 通知到所有
this.onAllCb(event, cbs, args)
}
// 监听所有
emitAll(callback) {
this.onAllCb = callback;
}
// 触发
remove(event, callback) {
if (!this.events[event]) {
return;
}
this.events[event] = {};
callback();
}
}
export default eventCenter;
原文链接:https://juejin.cn/post/7340307629892386856 作者:何日是归年