From 098639bbb74cd9bee1126d2f83e16b39dd1dc002 Mon Sep 17 00:00:00 2001 From: webfansplz <308241863@qq.com> Date: Sat, 25 Sep 2021 18:01:56 +0800 Subject: [PATCH] feat(watchOnce): new function (#765) * feat(watchOnce): new Function * chore(watchOnce): improve code * chore: simplify Co-authored-by: webfansplz <> Co-authored-by: Anthony Fu --- README.md | 2 +- indexes.json | 7 +++++++ packages/functions.md | 1 + packages/shared/index.ts | 1 + packages/shared/watchOnce/index.md | 20 ++++++++++++++++++++ packages/shared/watchOnce/index.test.ts | 16 ++++++++++++++++ packages/shared/watchOnce/index.ts | 21 +++++++++++++++++++++ 7 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 packages/shared/watchOnce/index.md create mode 100644 packages/shared/watchOnce/index.test.ts create mode 100644 packages/shared/watchOnce/index.ts diff --git a/README.md b/README.md index ab75d8a1d52c..5cbc847d745c 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Collection of essential Vue Composition Utilities NPM version NPM Downloads Docs & Demos -Function Count +Function Count
GitHub stars

diff --git a/indexes.json b/indexes.json index 65c4031cb1f8..b459d6259ca5 100644 --- a/indexes.json +++ b/indexes.json @@ -422,6 +422,13 @@ "category": "Watch", "description": "`watch` with the number of times triggered" }, + { + "name": "watchOnce", + "package": "shared", + "docs": "https://vueuse.org/shared/watchOnce/", + "category": "Watch", + "description": "`watch` with trigger once times" + }, { "name": "watchWithFilter", "package": "shared", diff --git a/packages/functions.md b/packages/functions.md index a33a860f7fb6..c928cfc69e2b 100644 --- a/packages/functions.md +++ b/packages/functions.md @@ -148,6 +148,7 @@ - [`throttledWatch`](https://vueuse.org/shared/throttledWatch/) — throttled watch - [`until`](https://vueuse.org/shared/until/) — promised one-time watch for changes - [`watchAtMost`](https://vueuse.org/shared/watchAtMost/) — `watch` with the number of times triggered + - [`watchOnce`](https://vueuse.org/shared/watchOnce/) — `watch` with trigger once times - [`watchWithFilter`](https://vueuse.org/shared/watchWithFilter/) — `watch` with additional EventFilter control - [`whenever`](https://vueuse.org/shared/whenever/) — shorthand for watching value to be truthy diff --git a/packages/shared/index.ts b/packages/shared/index.ts index 4367bf0d8777..21b9073c4768 100644 --- a/packages/shared/index.ts +++ b/packages/shared/index.ts @@ -40,5 +40,6 @@ export * from './useTimeoutFn' export * from './useToggle' export * from './utils' export * from './watchAtMost' +export * from './watchOnce' export * from './watchWithFilter' export * from './whenever' diff --git a/packages/shared/watchOnce/index.md b/packages/shared/watchOnce/index.md new file mode 100644 index 000000000000..6773408b5084 --- /dev/null +++ b/packages/shared/watchOnce/index.md @@ -0,0 +1,20 @@ +--- +category: Watch +--- + +# watchOnce + +`watch` that only triggers once. + +## Usage + +After the callback function has been triggered once, the watch will be stopped automatically. + +```ts +import { watchOnce } from '@vueuse/core' + +watchOnce(source, () => { + // triggers only once + console.log('source changed!') +}) +``` diff --git a/packages/shared/watchOnce/index.test.ts b/packages/shared/watchOnce/index.test.ts new file mode 100644 index 000000000000..3a4efb16d7e1 --- /dev/null +++ b/packages/shared/watchOnce/index.test.ts @@ -0,0 +1,16 @@ +import { ref, nextTick } from 'vue-demi' +import { watchOnce } from '.' + +describe('watchOnce', () => { + it('should work', async() => { + const num = ref(0) + const spy = jest.fn() + + watchOnce(num, spy) + num.value = 1 + await nextTick() + num.value = 2 + await nextTick() + expect(spy).toBeCalledTimes(1) + }) +}) diff --git a/packages/shared/watchOnce/index.ts b/packages/shared/watchOnce/index.ts new file mode 100644 index 000000000000..02cc38e1dfa8 --- /dev/null +++ b/packages/shared/watchOnce/index.ts @@ -0,0 +1,21 @@ +import { WatchSource, WatchCallback, WatchOptions, watch } from 'vue-demi' +import { MapOldSources, MapSources } from '../utils' + +// overlads +export function watchOnce[]>, Immediate extends Readonly = false>(source: T, cb: WatchCallback, MapOldSources>, options?: WatchOptions): void + +export function watchOnce[]>, Immediate extends Readonly = false>(source: T, cb: WatchCallback, MapOldSources>, options?: WatchOptions): void + +export function watchOnce = false>(sources: WatchSource, cb: WatchCallback, options?: WatchOptions): void + +// implementation +export function watchOnce = false>( + source: any, + cb: any, + options?: WatchOptions, +): void { + const stop = watch(source, (...args) => { + stop() + return cb(...args) + }, options) +}