mirror of https://github.com/vuejs/core.git
fix(watch): use maximum depth for duplicates (#13434)
This commit is contained in:
parent
99d54b28b4
commit
f2699a5cb3
|
@ -331,17 +331,17 @@ export function watch(
|
|||
export function traverse(
|
||||
value: unknown,
|
||||
depth: number = Infinity,
|
||||
seen?: Set<unknown>,
|
||||
seen?: Map<unknown, number>,
|
||||
): unknown {
|
||||
if (depth <= 0 || !isObject(value) || (value as any)[ReactiveFlags.SKIP]) {
|
||||
return value
|
||||
}
|
||||
|
||||
seen = seen || new Set()
|
||||
if (seen.has(value)) {
|
||||
seen = seen || new Map()
|
||||
if ((seen.get(value) || 0) >= depth) {
|
||||
return value
|
||||
}
|
||||
seen.add(value)
|
||||
seen.set(value, depth)
|
||||
depth--
|
||||
if (isRef(value)) {
|
||||
traverse(value.value, depth, seen)
|
||||
|
|
|
@ -1689,6 +1689,57 @@ describe('api: watch', () => {
|
|||
expect(cb).toHaveBeenCalledTimes(4)
|
||||
})
|
||||
|
||||
test('watching the same object at different depths', async () => {
|
||||
const arr1: any[] = reactive([[[{ foo: {} }]]])
|
||||
const arr2 = arr1[0]
|
||||
const arr3 = arr2[0]
|
||||
const obj = arr3[0]
|
||||
arr1.push(arr3)
|
||||
|
||||
const cb1 = vi.fn()
|
||||
const cb2 = vi.fn()
|
||||
const cb3 = vi.fn()
|
||||
const cb4 = vi.fn()
|
||||
watch(arr1, cb1, { deep: 1 })
|
||||
watch(arr1, cb2, { deep: 2 })
|
||||
watch(arr1, cb3, { deep: 3 })
|
||||
watch(arr1, cb4, { deep: 4 })
|
||||
|
||||
await nextTick()
|
||||
expect(cb1).toHaveBeenCalledTimes(0)
|
||||
expect(cb2).toHaveBeenCalledTimes(0)
|
||||
expect(cb3).toHaveBeenCalledTimes(0)
|
||||
expect(cb4).toHaveBeenCalledTimes(0)
|
||||
|
||||
obj.foo = {}
|
||||
await nextTick()
|
||||
expect(cb1).toHaveBeenCalledTimes(0)
|
||||
expect(cb2).toHaveBeenCalledTimes(0)
|
||||
expect(cb3).toHaveBeenCalledTimes(1)
|
||||
expect(cb4).toHaveBeenCalledTimes(1)
|
||||
|
||||
obj.foo.bar = 1
|
||||
await nextTick()
|
||||
expect(cb1).toHaveBeenCalledTimes(0)
|
||||
expect(cb2).toHaveBeenCalledTimes(0)
|
||||
expect(cb3).toHaveBeenCalledTimes(1)
|
||||
expect(cb4).toHaveBeenCalledTimes(2)
|
||||
|
||||
arr3.push(obj.foo)
|
||||
await nextTick()
|
||||
expect(cb1).toHaveBeenCalledTimes(0)
|
||||
expect(cb2).toHaveBeenCalledTimes(1)
|
||||
expect(cb3).toHaveBeenCalledTimes(2)
|
||||
expect(cb4).toHaveBeenCalledTimes(3)
|
||||
|
||||
obj.foo.bar = 2
|
||||
await nextTick()
|
||||
expect(cb1).toHaveBeenCalledTimes(0)
|
||||
expect(cb2).toHaveBeenCalledTimes(1)
|
||||
expect(cb3).toHaveBeenCalledTimes(3)
|
||||
expect(cb4).toHaveBeenCalledTimes(4)
|
||||
})
|
||||
|
||||
test('pause / resume', async () => {
|
||||
const count = ref(0)
|
||||
const cb = vi.fn()
|
||||
|
|
Loading…
Reference in New Issue