From a39ec871d4b2ff8cefbb1745be956db4e231d095 Mon Sep 17 00:00:00 2001 From: TuiMao233 <49724027+TuiMao233@users.noreply.github.com> Date: Fri, 3 Sep 2021 04:29:17 +0800 Subject: [PATCH] feat(useEventBus): new Function `once` (#680) Co-authored-by: Anthony Fu --- packages/core/useEventBus/index.test.ts | 11 +++++++++++ packages/core/useEventBus/index.ts | 21 ++++++++++++++++++--- packages/core/useEventBus/internal.ts | 4 ++-- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/packages/core/useEventBus/index.test.ts b/packages/core/useEventBus/index.test.ts index 8eb5c1e5be15..f7107b0d607d 100644 --- a/packages/core/useEventBus/index.test.ts +++ b/packages/core/useEventBus/index.test.ts @@ -24,6 +24,17 @@ describe('useEventBus', () => { reset() expect(events).toEqual(emptyMap) }) + it('once event', () => { + const { once, emit, reset } = useEventBus('foo') + const { inc, count } = useCounter(0) + once(inc) + emit() + emit() + emit() + expect(count.value).toBe(1) + reset() + expect(events).toEqual(emptyMap) + }) it('on callback off event', () => { const bus = useEventBus('on-callback-off') const { count, inc } = useCounter(0) diff --git a/packages/core/useEventBus/index.ts b/packages/core/useEventBus/index.ts index cb83c1a4ba14..53fffd231ab9 100644 --- a/packages/core/useEventBus/index.ts +++ b/packages/core/useEventBus/index.ts @@ -6,7 +6,7 @@ export type EventBusListener = (event: T) => void export type EventBusEvents = EventBusListener[] export interface EventBusKey extends Symbol { } -export type EventBusIdentifer = EventBusKey | string | number +export type EventBusIdentifier = EventBusKey | string | number export interface UseEventBusReturn { /** @@ -15,6 +15,12 @@ export interface UseEventBusReturn { * @returns a stop function to remove the current callback. */ on: (listener: EventBusListener) => Fn + /** + * Similar to `on`, but only fires once + * @param listener watch listener. + * @returns a stop function to remove the current callback. + */ + once: (listener: EventBusListener) => Fn /** * Emit an event, the corresponding event listeners will execute. * @param event data sent. @@ -31,7 +37,7 @@ export interface UseEventBusReturn { reset: () => void } -export function useEventBus(key: EventBusIdentifer): UseEventBusReturn { +export function useEventBus(key: EventBusIdentifier): UseEventBusReturn { const scope = getCurrentScope() function on(listener: EventBusListener) { @@ -45,6 +51,15 @@ export function useEventBus(key: EventBusIdentifer): UseEventBus return _off } + function once(listener: EventBusListener) { + function _listener(...args: any[]) { + off(_listener) + // @ts-expect-error + listener(...args) + } + return on(_listener) + } + function off(listener: EventBusListener): void { const listeners = events.get(key) if (!listeners) @@ -65,5 +80,5 @@ export function useEventBus(key: EventBusIdentifer): UseEventBus events.get(key)?.forEach(v => v(event)) } - return { on, off, emit, reset } + return { on, once, off, emit, reset } } diff --git a/packages/core/useEventBus/internal.ts b/packages/core/useEventBus/internal.ts index fce450104700..03f02ab612ab 100644 --- a/packages/core/useEventBus/internal.ts +++ b/packages/core/useEventBus/internal.ts @@ -1,4 +1,4 @@ -import { EventBusEvents, EventBusIdentifer } from '.' +import { EventBusEvents, EventBusIdentifier } from '.' /* #__PURE__ */ -export const events = new Map, EventBusEvents>() +export const events = new Map, EventBusEvents>()