go-view/src/hooks/useEventBus.hook.ts
2022-07-21 10:33:40 +08:00

68 lines
1.3 KiB
TypeScript

import Emitter from 'tiny-emitter'
import { onBeforeUnmount } from 'vue'
/**
* {
* on: {
* [event]: []
* },
* }
*/
type EventBusListeners = {
[key: string]: () => any
};
export type EventBusOptions = {
on?: EventBusListeners
once?: EventBusListeners
}
//@ts-ignore
const bus = new Emitter()
const addListeners = (listeners: EventBusListeners | undefined, isOnce = false): void => {
if(!listeners) return
Object.keys(listeners).forEach(key => {
console.info('监听事件:', key)
bus[isOnce ? 'once' : 'on'](key, listeners[key])
onBeforeUnmount(() => {
bus.off(key, listeners[key])
})
})
}
// 转换事件名
const convertListeners = (listeners: EventBusListeners, dst: object, prefix = 'prefix'): void => {
Object.keys(listeners).forEach((key: string) => {
// @ts-ignore
dst[`${prefix}:${key}`] = listeners[key]
})
}
export const convertEventBusListeners = (listeners: EventBusOptions, prefix: string): EventBusOptions => {
const res = {
on: {},
once: {},
}
if(listeners.on) {
convertListeners(listeners.on, res.on, prefix)
}
if(listeners.once) {
convertListeners(listeners.once, res.once, prefix)
}
return res
}
export const useEventBus = (listeners: EventBusOptions = {}) => {
addListeners(listeners.on);
addListeners(listeners.once, true)
return bus
}