Skip to content

Instantly share code, notes, and snippets.

@tachibana-shin
Last active June 25, 2023 13:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tachibana-shin/d3139d3f24f51d81cf890439d3a05d0c to your computer and use it in GitHub Desktop.
Save tachibana-shin/d3139d3f24f51d81cf890439d3a05d0c to your computer and use it in GitHub Desktop.
Event bus for vue and reactivity system
import { getCurrentScope, onScopeDispose } from "vue"
class EventBus<Events extends Record<string, unknown>> {
private readonly store = new Map<keyof Events, Set<(param: any) =>void>>()
constructor() {
this.on = this.on.bind(this)
this.off = this.off.bind(this)
this.emit = this.emit.bind(this)
}
on<Name extends keyof Events>(name: Name, cb: (param: Events[Name]) => void): () => void {
let smap = this.store.get(name)
if (!smap) this.store.set(name, smap = new Set())
smap.add(cb)
const stop = () => void this.store.get(name)?.delete(cb)
const scope = getCurrentScope()
if (scope) onScopeDispose(() => stop)
return stop
}
off<Name extends keyof Events>(name: Name, cb?: (param: Events[Name]) => void): void {
if (cb)
this.store.get(name)?.delete(cb)
else
this.store.delete(name)
}
emit<Name extends keyof Events>(name: Name, param: Events[Name]): void {
this.store.get(name)?.forEach(cb => cb(param))
}
}
export function defineBus<Events extends Record<string, unknown>>() {
const bus = new EventBus<Events>()
return () => bus
}
/**
* @Usage:
* bus.ts:
* ```ts
* export default defineBus<{ hello: name }()
* ```
* main.ts
* import useBus from "./bus"
*
* const { on, off, emit } = useBus()
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment