Skip to content

Commit 6d857f5

Browse files
committed
fix(watch): new property addition should trigger deep watcher with getter
close #12967 close #12972
1 parent a174c29 commit 6d857f5

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

src/v3/apiWatch.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,11 @@ function doWatch(
185185
}
186186

187187
const instance = currentInstance
188-
const call = (fn: Function, type: string, args: any[] | null = null) =>
189-
invokeWithErrorHandling(fn, null, args, instance, type)
188+
const call = (fn: Function, type: string, args: any[] | null = null) => {
189+
const res = invokeWithErrorHandling(fn, null, args, instance, type)
190+
if (deep && res && res.__ob__) res.__ob__.dep.depend()
191+
return res
192+
}
190193

191194
let getter: () => any
192195
let forceTrigger = false
@@ -209,6 +212,7 @@ function doWatch(
209212
if (isRef(s)) {
210213
return s.value
211214
} else if (isReactive(s)) {
215+
s.__ob__.dep.depend()
212216
return traverse(s)
213217
} else if (isFunction(s)) {
214218
return call(s, WATCHER_GETTER)

test/unit/features/v3/apiWatch.spec.ts

+31
Original file line numberDiff line numberDiff line change
@@ -1200,4 +1200,35 @@ describe('api: watch', () => {
12001200
expect(parentSpy).toHaveBeenCalledTimes(1)
12011201
expect(childSpy).toHaveBeenCalledTimes(1)
12021202
})
1203+
1204+
// #12967
1205+
test('trigger when adding new property with Vue.set (getter)', async () => {
1206+
const spy = vi.fn()
1207+
const r = reactive({ exist: 5 })
1208+
watch(() => r, spy, { deep: true })
1209+
set(r, 'add', 1)
1210+
1211+
await nextTick()
1212+
expect(spy).toHaveBeenCalledTimes(1)
1213+
})
1214+
1215+
test('trigger when adding new property with Vue.set (getter in array source)', async () => {
1216+
const spy = vi.fn()
1217+
const r = reactive({ exist: 5 })
1218+
watch([() => r], spy, { deep: true })
1219+
set(r, 'add', 1)
1220+
1221+
await nextTick()
1222+
expect(spy).toHaveBeenCalledTimes(1)
1223+
})
1224+
1225+
test('trigger when adding new property with Vue.set (reactive in array source)', async () => {
1226+
const spy = vi.fn()
1227+
const r = reactive({ exist: 5 })
1228+
watch([r], spy, { deep: true })
1229+
set(r, 'add', 1)
1230+
1231+
await nextTick()
1232+
expect(spy).toHaveBeenCalledTimes(1)
1233+
})
12031234
})

0 commit comments

Comments
 (0)