Skip to content

Commit

Permalink
fix(watch): support traversing symbol properties in deep watcher (#10969
Browse files Browse the repository at this point in the history
)

close #402
  • Loading branch information
skirtles-code authored May 30, 2024
1 parent 6f9587f commit a3e8aaf
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
46 changes: 46 additions & 0 deletions packages/runtime-core/__tests__/apiWatch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,52 @@ describe('api: watch', () => {
expect(dummy).toEqual([1, 2])
})

it('deep with symbols', async () => {
const symbol1 = Symbol()
const symbol2 = Symbol()
const symbol3 = Symbol()
const symbol4 = Symbol()

const raw: any = {
[symbol1]: {
[symbol2]: 1,
},
}

Object.defineProperty(raw, symbol3, {
writable: true,
enumerable: false,
value: 1,
})

const state = reactive(raw)
const spy = vi.fn()

watch(() => state, spy, { deep: true })

await nextTick()
expect(spy).toHaveBeenCalledTimes(0)

state[symbol1][symbol2] = 2
await nextTick()
expect(spy).toHaveBeenCalledTimes(1)

// Non-enumerable properties don't trigger deep watchers
state[symbol3] = 3
await nextTick()
expect(spy).toHaveBeenCalledTimes(1)

// Adding a new symbol property
state[symbol4] = 1
await nextTick()
expect(spy).toHaveBeenCalledTimes(2)

// Removing a symbol property
delete state[symbol4]
await nextTick()
expect(spy).toHaveBeenCalledTimes(3)
})

it('immediate', async () => {
const count = ref(0)
const cb = vi.fn()
Expand Down
5 changes: 5 additions & 0 deletions packages/runtime-core/src/apiWatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,11 @@ export function traverse(
for (const key in value) {
traverse(value[key], depth, seen)
}
for (const key of Object.getOwnPropertySymbols(value)) {
if (Object.prototype.propertyIsEnumerable.call(value, key)) {
traverse(value[key as any], depth, seen)
}
}
}
return value
}

0 comments on commit a3e8aaf

Please sign in to comment.