Skip to content

Commit

Permalink
fix(runtime-core): support deep: false when watch reactive
Browse files Browse the repository at this point in the history
  • Loading branch information
RicardoErii committed Dec 26, 2023
1 parent a8d0b1b commit 2bab130
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 2 deletions.
32 changes: 32 additions & 0 deletions packages/runtime-core/__tests__/apiWatch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,38 @@ describe('api: watch', () => {
expect(dummy).toBe(1)
})

it('directly watching reactive object: deep: false', async () => {
const src = reactive({
state: {
count: 0
}
})
let dummy
watch(
src,
({ state }) => {
dummy = state
},
{
deep: false
}
)
src.state.count++
await nextTick()
expect(dummy).toBe(undefined)
})

it('directly watching reactive array', async () => {
const src = reactive([0])
let dummy
watch(src, v => {
dummy = v
})
src.push(1)
await nextTick()
expect(dummy).toMatchObject([0, 1])
})

it('watching multiple sources', async () => {
const state = reactive({ count: 1 })
const count = ref(1)
Expand Down
25 changes: 23 additions & 2 deletions packages/runtime-core/src/apiWatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,9 @@ function doWatch(
getter = () => source.value
forceTrigger = isShallow(source)
} else if (isReactive(source)) {
getter = () => source
deep = true
deep = isShallow(source) ? false : deep ?? true
getter = deep ? () => source : () => shallowTraverse(source)
forceTrigger = true
} else if (isArray(source)) {
isMultiSource = true
forceTrigger = source.some(s => isReactive(s) || isShallow(s))
Expand Down Expand Up @@ -464,3 +465,23 @@ export function traverse(value: unknown, seen?: Set<unknown>) {
}
return value
}

export function shallowTraverse(value: unknown) {
if (!isObject(value) || (value as any)[ReactiveFlags.SKIP]) {
return value
}
if (isArray(value)) {
for (let i = 0; i < value.length; i++) {
value[i]
}
} else if (isSet(value) || isMap(value)) {
value.forEach((v: any) => {
v
})
} else if (isPlainObject(value)) {
for (const key in value) {
value[key]
}
}
return value
}

0 comments on commit 2bab130

Please sign in to comment.