|
|
@@ -1,18 +1,18 @@
|
|
|
import { v4 } from 'uuid'
|
|
|
-import { EventKey, MessageEvent } from './types'
|
|
|
+import { EventKey, EventBus } from './types'
|
|
|
|
|
|
/**
|
|
|
* 事件总线
|
|
|
*/
|
|
|
export default new (class {
|
|
|
- private eventMap = new Map<string, MessageEvent>();
|
|
|
+ private events = new Map<string, EventBus>()
|
|
|
|
|
|
/** 监听事件 */
|
|
|
- $on(eventKey: EventKey | EventKey[], callback: MessageEvent['callback'], once = false) {
|
|
|
- const uuid = v4();
|
|
|
- const keys = Array.isArray(eventKey) ? eventKey : [eventKey];
|
|
|
+ $on(eventKey: EventKey | EventKey[], callback: EventBus['callback'], once = false) {
|
|
|
+ const uuid = v4()
|
|
|
+ const keys = Array.isArray(eventKey) ? eventKey : [eventKey]
|
|
|
|
|
|
- this.eventMap.set(uuid, {
|
|
|
+ this.events.set(uuid, {
|
|
|
keys,
|
|
|
once,
|
|
|
callback
|
|
|
@@ -21,35 +21,40 @@ export default new (class {
|
|
|
/** 销毁事件,注意离开页面时要手动销毁当前页面订阅的事件,防止事件重复触发 */
|
|
|
return {
|
|
|
uuid,
|
|
|
- cancel: () => this.eventMap.delete(uuid)
|
|
|
+ cancel: () => this.events.delete(uuid)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/** 触发事件 */
|
|
|
$emit(eventKey: EventKey, ...data: unknown[]) {
|
|
|
- for (const [uuid, e] of this.eventMap.entries()) {
|
|
|
+ for (const [uuid, e] of this.events.entries()) {
|
|
|
if (e.keys.includes(eventKey)) {
|
|
|
- e.callback(...data);
|
|
|
- e.once && this.eventMap.delete(uuid);
|
|
|
+ e.callback(...data)
|
|
|
+ e.once && this.events.delete(uuid)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/** 取消事件 */
|
|
|
- $off(...eventkeys: EventKey[]) {
|
|
|
- if (eventkeys.length) {
|
|
|
- for (const [uuid, e] of this.eventMap.entries()) {
|
|
|
- for (let i = e.keys.length - 1; i >= 0; i--) {
|
|
|
- if (eventkeys.includes(e.keys[i])) {
|
|
|
- e.keys.splice(i, 1);
|
|
|
- }
|
|
|
- }
|
|
|
- if (!e.keys.length) {
|
|
|
- this.eventMap.delete(uuid);
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- this.eventMap.clear();
|
|
|
+ $off(...eventKeys: EventKey[]) {
|
|
|
+ const keySet = new Set(eventKeys)
|
|
|
+ const uuidsToDelete = new Set<string>()
|
|
|
+
|
|
|
+ for (const [uuid, e] of this.events) {
|
|
|
+ // 使用 filter 方法来创建一个新的 keys 数组,只包含未被取消的事件键
|
|
|
+ const remainingKeys = e.keys.filter(key => !keySet.has(key))
|
|
|
+ if (remainingKeys.length === 0) {
|
|
|
+ // 如果没有剩余的事件键,则添加 UUID 到删除集合中
|
|
|
+ uuidsToDelete.add(uuid)
|
|
|
+ } else if (remainingKeys.length !== e.keys.length) {
|
|
|
+ // 如果事件键被部分取消,则更新事件的 keys 数组
|
|
|
+ this.events.set(uuid, { ...e, keys: remainingKeys })
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
+
|
|
|
+ // 在遍历完成后,删除需要删除的事件
|
|
|
+ for (const uuid of uuidsToDelete) {
|
|
|
+ this.events.delete(uuid)
|
|
|
+ }
|
|
|
+ }
|
|
|
})
|