fix(runtime-core/watch): trigger watcher with undefined as initial value (#687)
Fix #683
This commit is contained in:
parent
3ddb441c56
commit
5742a0b826
@ -27,6 +27,33 @@ describe('api: watch', () => {
|
|||||||
expect(dummy).toBe(1)
|
expect(dummy).toBe(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('triggers when initial value is null', async () => {
|
||||||
|
const state = ref(null)
|
||||||
|
const spy = jest.fn()
|
||||||
|
watch(() => state.value, spy)
|
||||||
|
await nextTick()
|
||||||
|
expect(spy).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('triggers when initial value is undefined', async () => {
|
||||||
|
const state = ref()
|
||||||
|
const spy = jest.fn()
|
||||||
|
watch(() => state.value, spy)
|
||||||
|
await nextTick()
|
||||||
|
expect(spy).toHaveBeenCalled()
|
||||||
|
state.value = 3
|
||||||
|
await nextTick()
|
||||||
|
expect(spy).toHaveBeenCalledTimes(2)
|
||||||
|
// testing if undefined can trigger the watcher
|
||||||
|
state.value = undefined
|
||||||
|
await nextTick()
|
||||||
|
expect(spy).toHaveBeenCalledTimes(3)
|
||||||
|
// it shouldn't trigger if the same value is set
|
||||||
|
state.value = undefined
|
||||||
|
await nextTick()
|
||||||
|
expect(spy).toHaveBeenCalledTimes(3)
|
||||||
|
})
|
||||||
|
|
||||||
it('watching single source: getter', async () => {
|
it('watching single source: getter', async () => {
|
||||||
const state = reactive({ count: 0 })
|
const state = reactive({ count: 0 })
|
||||||
let dummy
|
let dummy
|
||||||
|
@ -61,6 +61,9 @@ export type StopHandle = () => void
|
|||||||
|
|
||||||
const invoke = (fn: Function) => fn()
|
const invoke = (fn: Function) => fn()
|
||||||
|
|
||||||
|
// initial value for watchers to trigger on undefined initial values
|
||||||
|
const INITIAL_WATCHER_VALUE = {}
|
||||||
|
|
||||||
// overload #1: simple effect
|
// overload #1: simple effect
|
||||||
export function watch(effect: WatchEffect, options?: WatchOptions): StopHandle
|
export function watch(effect: WatchEffect, options?: WatchOptions): StopHandle
|
||||||
|
|
||||||
@ -153,7 +156,7 @@ function doWatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let oldValue = isArray(source) ? [] : undefined
|
let oldValue = isArray(source) ? [] : INITIAL_WATCHER_VALUE
|
||||||
const applyCb = cb
|
const applyCb = cb
|
||||||
? () => {
|
? () => {
|
||||||
if (instance && instance.isUnmounted) {
|
if (instance && instance.isUnmounted) {
|
||||||
@ -167,7 +170,8 @@ function doWatch(
|
|||||||
}
|
}
|
||||||
callWithAsyncErrorHandling(cb, instance, ErrorCodes.WATCH_CALLBACK, [
|
callWithAsyncErrorHandling(cb, instance, ErrorCodes.WATCH_CALLBACK, [
|
||||||
newValue,
|
newValue,
|
||||||
oldValue,
|
// pass undefined as the old value when it's changed for the first time
|
||||||
|
oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,
|
||||||
registerCleanup
|
registerCleanup
|
||||||
])
|
])
|
||||||
oldValue = newValue
|
oldValue = newValue
|
||||||
|
Loading…
x
Reference in New Issue
Block a user