diff --git a/src/v3/apiWatch.ts b/src/v3/apiWatch.ts index 52be4d32e4c..6a0b65fa298 100644 --- a/src/v3/apiWatch.ts +++ b/src/v3/apiWatch.ts @@ -196,12 +196,10 @@ function doWatch( getter = () => source.value forceTrigger = isShallow(source) } else if (isReactive(source)) { - getter = isArray(source) - ? () => { - ;(source as any).__ob__.dep.depend() - return source - } - : () => source + getter = () => { + ;(source as any).__ob__.dep.depend() + return source + } deep = true } else if (isArray(source)) { isMultiSource = true diff --git a/src/v3/reactivity/ref.ts b/src/v3/reactivity/ref.ts index f7026df05a1..114e6f563d8 100644 --- a/src/v3/reactivity/ref.ts +++ b/src/v3/reactivity/ref.ts @@ -68,7 +68,7 @@ function createRef(rawValue: unknown, shallow: boolean) { } const ref: any = {} def(ref, RefFlag, true) - def(ref, ReactiveFlags.IS_SHALLOW, true) + def(ref, ReactiveFlags.IS_SHALLOW, shallow) def( ref, 'dep', diff --git a/test/unit/features/v3/apiWatch.spec.ts b/test/unit/features/v3/apiWatch.spec.ts index 41870ad1d51..52025afa96a 100644 --- a/test/unit/features/v3/apiWatch.spec.ts +++ b/test/unit/features/v3/apiWatch.spec.ts @@ -1136,4 +1136,21 @@ describe('api: watch', () => { await nextTick() expect(spy).toHaveBeenCalledTimes(2) }) + + // #12643 + test('should trigger watch on reactive object when new property is added via set()', () => { + const spy = vi.fn() + const obj = reactive({}) + watch(obj, spy, { flush: 'sync' }) + set(obj, 'foo', 1) + expect(spy).toHaveBeenCalled() + }) + + test('should not trigger watch when calling set() on ref value', () => { + const spy = vi.fn() + const r = ref({}) + watch(r, spy, { flush: 'sync' }) + set(r.value, 'foo', 1) + expect(spy).not.toHaveBeenCalled() + }) })