Skip to content

Commit bd946aa

Browse files
authored
feat(whenever): override once option (#3800)
1 parent 1b67d96 commit bd946aa

File tree

2 files changed

+69
-5
lines changed

2 files changed

+69
-5
lines changed

packages/shared/whenever/index.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,50 @@ describe('whenever', () => {
5757

5858
vm.unmount()
5959
})
60+
61+
it('once', async () => {
62+
const vm = useSetup(() => {
63+
const number = ref<number | null | undefined>(1)
64+
const watchCount = ref(0)
65+
const watchValue: Ref<number | undefined> = ref()
66+
67+
whenever(number, (value) => {
68+
watchCount.value += 1
69+
watchValue.value = value
70+
expectType<number>(value)
71+
// @ts-expect-error value should be of type number
72+
expectType<undefined>(value)
73+
// @ts-expect-error value should be of type number
74+
expectType<null>(value)
75+
// @ts-expect-error value should be of type number
76+
expectType<string>(value)
77+
}, { once: true })
78+
79+
const changeNumber = (v: number) => number.value = v
80+
81+
return {
82+
number,
83+
watchCount,
84+
watchValue,
85+
changeNumber,
86+
}
87+
})
88+
89+
vm.changeNumber(0)
90+
await nextTick()
91+
expect(toValue(vm.watchCount)).toEqual(0)
92+
expect(toValue(vm.watchValue)).toBeUndefined()
93+
94+
vm.changeNumber(1)
95+
await nextTick()
96+
expect(toValue(vm.watchCount)).toEqual(1)
97+
expect(toValue(vm.watchValue)).toEqual(1)
98+
99+
vm.changeNumber(2)
100+
await nextTick()
101+
expect(toValue(vm.watchCount)).toEqual(1)
102+
expect(toValue(vm.watchValue)).toEqual(1)
103+
104+
vm.unmount()
105+
})
60106
})

packages/shared/whenever/index.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,36 @@
11
import type { WatchCallback, WatchOptions, WatchSource } from 'vue-demi'
2-
import { watch } from 'vue-demi'
2+
import { nextTick, watch } from 'vue-demi'
3+
4+
export interface WheneverOptions extends WatchOptions {
5+
/**
6+
* Only trigger once when the condition is met
7+
*
8+
* Override the `once` option in `WatchOptions`
9+
*
10+
* @default false
11+
*/
12+
once?: boolean
13+
}
314

415
/**
516
* Shorthand for watching value to be truthy
617
*
718
* @see https://vueuse.org/whenever
819
*/
9-
export function whenever<T>(source: WatchSource<T | false | null | undefined>, cb: WatchCallback<T>, options?: WatchOptions) {
10-
return watch(
20+
export function whenever<T>(source: WatchSource<T | false | null | undefined>, cb: WatchCallback<T>, options?: WheneverOptions) {
21+
const stop = watch(
1122
source,
1223
(v, ov, onInvalidate) => {
13-
if (v)
24+
if (v) {
25+
if (options?.once)
26+
nextTick(() => stop())
1427
cb(v, ov, onInvalidate)
28+
}
1529
},
16-
options,
30+
{
31+
...options,
32+
once: false,
33+
} as WatchOptions,
1734
)
35+
return stop
1836
}

0 commit comments

Comments
 (0)