Skip to content

Commit

Permalink
feat(whenever): override once option (#3800)
Browse files Browse the repository at this point in the history
  • Loading branch information
chizukicn committed Feb 27, 2024
1 parent 1b67d96 commit bd946aa
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 5 deletions.
46 changes: 46 additions & 0 deletions packages/shared/whenever/index.test.ts
Expand Up @@ -57,4 +57,50 @@ describe('whenever', () => {

vm.unmount()
})

it('once', async () => {
const vm = useSetup(() => {
const number = ref<number | null | undefined>(1)
const watchCount = ref(0)
const watchValue: Ref<number | undefined> = ref()

whenever(number, (value) => {
watchCount.value += 1
watchValue.value = value
expectType<number>(value)
// @ts-expect-error value should be of type number
expectType<undefined>(value)
// @ts-expect-error value should be of type number
expectType<null>(value)
// @ts-expect-error value should be of type number
expectType<string>(value)
}, { once: true })

const changeNumber = (v: number) => number.value = v

return {
number,
watchCount,
watchValue,
changeNumber,
}
})

vm.changeNumber(0)
await nextTick()
expect(toValue(vm.watchCount)).toEqual(0)
expect(toValue(vm.watchValue)).toBeUndefined()

vm.changeNumber(1)
await nextTick()
expect(toValue(vm.watchCount)).toEqual(1)
expect(toValue(vm.watchValue)).toEqual(1)

vm.changeNumber(2)
await nextTick()
expect(toValue(vm.watchCount)).toEqual(1)
expect(toValue(vm.watchValue)).toEqual(1)

vm.unmount()
})
})
28 changes: 23 additions & 5 deletions packages/shared/whenever/index.ts
@@ -1,18 +1,36 @@
import type { WatchCallback, WatchOptions, WatchSource } from 'vue-demi'
import { watch } from 'vue-demi'
import { nextTick, watch } from 'vue-demi'

export interface WheneverOptions extends WatchOptions {
/**
* Only trigger once when the condition is met
*
* Override the `once` option in `WatchOptions`
*
* @default false
*/
once?: boolean
}

/**
* Shorthand for watching value to be truthy
*
* @see https://vueuse.org/whenever
*/
export function whenever<T>(source: WatchSource<T | false | null | undefined>, cb: WatchCallback<T>, options?: WatchOptions) {
return watch(
export function whenever<T>(source: WatchSource<T | false | null | undefined>, cb: WatchCallback<T>, options?: WheneverOptions) {
const stop = watch(
source,
(v, ov, onInvalidate) => {
if (v)
if (v) {
if (options?.once)
nextTick(() => stop())
cb(v, ov, onInvalidate)
}
},
options,
{
...options,
once: false,
} as WatchOptions,
)
return stop
}

0 comments on commit bd946aa

Please sign in to comment.