From ec987530b966f93d3fc9cae0a9658e15da06d153 Mon Sep 17 00:00:00 2001 From: neverland Date: Sat, 4 Feb 2023 21:13:38 +0800 Subject: [PATCH] feat(@vant/use): support cleanup useEventListener (#11540) --- .../vant-use/src/useEventListener/index.ts | 34 ++++++++++++++++--- .../docs/markdown/use-event-listener.en-US.md | 21 +++++++++++- .../docs/markdown/use-event-listener.zh-CN.md | 21 +++++++++++- 3 files changed, 70 insertions(+), 6 deletions(-) diff --git a/packages/vant-use/src/useEventListener/index.ts b/packages/vant-use/src/useEventListener/index.ts index ffd4dfe08..f20f88b2f 100644 --- a/packages/vant-use/src/useEventListener/index.ts +++ b/packages/vant-use/src/useEventListener/index.ts @@ -1,4 +1,12 @@ -import { Ref, watch, isRef, unref, onUnmounted, onDeactivated } from 'vue'; +import { + Ref, + watch, + isRef, + unref, + onUnmounted, + onDeactivated, + type WatchStopHandle, +} from 'vue'; import { onMountedOrActivated } from '../onMountedOrActivated'; import { inBrowser } from '../utils'; @@ -14,12 +22,12 @@ export function useEventListener( type: K, listener: (event: DocumentEventMap[K]) => void, options?: UseEventListenerOptions -): void; +): () => void; export function useEventListener( type: string, listener: EventListener, options?: UseEventListenerOptions -): void; +): () => void; export function useEventListener( type: string, listener: EventListener, @@ -31,9 +39,13 @@ export function useEventListener( const { target = window, passive = false, capture = false } = options; + let cleaned = false; let attached: boolean; const add = (target?: TargetRef) => { + if (cleaned) { + return; + } const element = unref(target); if (element && !attached) { @@ -46,6 +58,9 @@ export function useEventListener( }; const remove = (target?: TargetRef) => { + if (cleaned) { + return; + } const element = unref(target); if (element && attached) { @@ -58,10 +73,21 @@ export function useEventListener( onDeactivated(() => remove(target)); onMountedOrActivated(() => add(target)); + let stopWatch: WatchStopHandle; + if (isRef(target)) { - watch(target, (val, oldVal) => { + stopWatch = watch(target, (val, oldVal) => { remove(oldVal); add(val); }); } + + /** + * Clean up the event listener + */ + return () => { + stopWatch?.(); + remove(target); + cleaned = true; + }; } diff --git a/packages/vant/docs/markdown/use-event-listener.en-US.md b/packages/vant/docs/markdown/use-event-listener.en-US.md index b36e84808..6f4d05246 100644 --- a/packages/vant/docs/markdown/use-event-listener.en-US.md +++ b/packages/vant/docs/markdown/use-event-listener.en-US.md @@ -31,6 +31,25 @@ export default { }; ``` +### Remove Event Listener + +`useEventListener` will return a `cleanup` function,you can call it to remove the event listener. + +```js +import { ref } from 'vue'; +import { useEventListener } from '@vant/use'; + +export default { + setup() { + const cleanup = useEventListener('resize', () => { + console.log('window resize'); + }); + + cleanup(); + }, +}; +``` + ## API ### Type Declarations @@ -46,7 +65,7 @@ function useEventListener( type: string, listener: EventListener, options?: Options -): void; +): () => void; ``` ### Params diff --git a/packages/vant/docs/markdown/use-event-listener.zh-CN.md b/packages/vant/docs/markdown/use-event-listener.zh-CN.md index a8fe6a6df..42b39e604 100644 --- a/packages/vant/docs/markdown/use-event-listener.zh-CN.md +++ b/packages/vant/docs/markdown/use-event-listener.zh-CN.md @@ -32,6 +32,25 @@ export default { }; ``` +### 取消事件监听 + +`useEventListener` 会返回一个 `cleanup` 函数,调用该函数可以取消事件监听。 + +```js +import { ref } from 'vue'; +import { useEventListener } from '@vant/use'; + +export default { + setup() { + const cleanup = useEventListener('resize', () => { + console.log('window resize'); + }); + + cleanup(); + }, +}; +``` + ## API ### 类型定义 @@ -47,7 +66,7 @@ function useEventListener( type: string, listener: EventListener, options?: Options -): void; +): () => void; ``` ### 参数