fix(watch): new property addition should trigger deep watcher with getter

close #12967
close #12972
This commit is contained in:
Evan You 2023-12-07 00:13:31 +08:00
parent a174c29dab
commit 6d857f5bee
2 changed files with 37 additions and 2 deletions

View File

@ -185,8 +185,11 @@ function doWatch(
}
const instance = currentInstance
const call = (fn: Function, type: string, args: any[] | null = null) =>
invokeWithErrorHandling(fn, null, args, instance, type)
const call = (fn: Function, type: string, args: any[] | null = null) => {
const res = invokeWithErrorHandling(fn, null, args, instance, type)
if (deep && res && res.__ob__) res.__ob__.dep.depend()
return res
}
let getter: () => any
let forceTrigger = false
@ -209,6 +212,7 @@ function doWatch(
if (isRef(s)) {
return s.value
} else if (isReactive(s)) {
s.__ob__.dep.depend()
return traverse(s)
} else if (isFunction(s)) {
return call(s, WATCHER_GETTER)

View File

@ -1200,4 +1200,35 @@ describe('api: watch', () => {
expect(parentSpy).toHaveBeenCalledTimes(1)
expect(childSpy).toHaveBeenCalledTimes(1)
})
// #12967
test('trigger when adding new property with Vue.set (getter)', async () => {
const spy = vi.fn()
const r = reactive({ exist: 5 })
watch(() => r, spy, { deep: true })
set(r, 'add', 1)
await nextTick()
expect(spy).toHaveBeenCalledTimes(1)
})
test('trigger when adding new property with Vue.set (getter in array source)', async () => {
const spy = vi.fn()
const r = reactive({ exist: 5 })
watch([() => r], spy, { deep: true })
set(r, 'add', 1)
await nextTick()
expect(spy).toHaveBeenCalledTimes(1)
})
test('trigger when adding new property with Vue.set (reactive in array source)', async () => {
const spy = vi.fn()
const r = reactive({ exist: 5 })
watch([r], spy, { deep: true })
set(r, 'add', 1)
await nextTick()
expect(spy).toHaveBeenCalledTimes(1)
})
})