直接上代码,创建一个onfire.ts文件
export interface Listener {
cb: Function
once: boolean
}
export interface EventsType {
[eventName: string]: Listener[]
}
export default class OnFire {
static ver = '__VERSION__'
// 所有事件的监听器
es: EventsType = {}
on(eventName: string, cb: Function, once: boolean = false) {
if (!this.es[eventName]) {
this.es[eventName] = []
}
this.es[eventName].push({
cb,
once,
})
}
once(eventName: string, cb: Function) {
this.on(eventName, cb, true)
}
fire(eventName: string, ...params: any[]) {
const listeners = this.es[eventName] || []
let l = listeners.length
for (let i = 0; i < l; i++) {
const { cb, once } = listeners[i]
cb.apply(this, params)
if (once) {
listeners.splice(i, 1)
i--
l--
}
}
}
off(eventName?: string, cb?: Function) {
// clean all
if (eventName === undefined) {
this.es = {}
} else {
if (cb === undefined) {
// clean the eventName's listeners
delete this.es[eventName]
} else {
const listeners = this.es[eventName] || []
// clean the event and listener
let l = listeners.length
for (let i = 0; i < l; i++) {
if (listeners[i].cb === cb) {
listeners.splice(i, 1)
i--
l--
}
}
}
}
}
// cname of fire
emit(eventName: string, ...params: any[]) {
this.fire(eventName, ...params)
}
}
然后创建一个eventBus.ts
import EE from './onfire'
export const EVENT_AUTO_LAYOUT = 'AUTO_LAYOUT'
export default new EE()
然后封装useEventBus
import { useEffect } from 'react'
import eventBus from '../utils/eventBus'
interface UseEventType {
type: string
onChange: any
}
const useEventBus = ({ type, onChange }: UseEventType, dep = []) => {
useEffect(() => {
eventBus.on(type, onChange)
return () => {
eventBus.off(type, onChange)
}
}, [type, onChange, dep])
}
export default useEventBus
如何使用呢?
传递的一方
eventBus.emit(EVENT_NODE_MOVING, '德玛西亚')
接收的一方
const handleAutoLayout = useCallback((name) => {
console.log(name); // 德玛西亚
}, []);
useEventBus({ type: EVENT_NODE_MOVING, onChange: handleAutoLayout })