fix(reactivity): fix watch behavior inconsistency + deep ref shallow check

fix #12643
This commit is contained in:
Evan You 2022-07-12 18:50:01 +08:00
parent 0825d3087f
commit 98fb01c79c
3 changed files with 22 additions and 7 deletions

View File

@ -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

View File

@ -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',

View File

@ -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()
})
})