Skip to content

Commit 2bab130

Browse files
author
RicardoErii
committed
fix(runtime-core): support deep: false when watch reactive
1 parent a8d0b1b commit 2bab130

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

packages/runtime-core/__tests__/apiWatch.spec.ts

+32
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,38 @@ describe('api: watch', () => {
156156
expect(dummy).toBe(1)
157157
})
158158

159+
it('directly watching reactive object: deep: false', async () => {
160+
const src = reactive({
161+
state: {
162+
count: 0
163+
}
164+
})
165+
let dummy
166+
watch(
167+
src,
168+
({ state }) => {
169+
dummy = state
170+
},
171+
{
172+
deep: false
173+
}
174+
)
175+
src.state.count++
176+
await nextTick()
177+
expect(dummy).toBe(undefined)
178+
})
179+
180+
it('directly watching reactive array', async () => {
181+
const src = reactive([0])
182+
let dummy
183+
watch(src, v => {
184+
dummy = v
185+
})
186+
src.push(1)
187+
await nextTick()
188+
expect(dummy).toMatchObject([0, 1])
189+
})
190+
159191
it('watching multiple sources', async () => {
160192
const state = reactive({ count: 1 })
161193
const count = ref(1)

packages/runtime-core/src/apiWatch.ts

+23-2
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,9 @@ function doWatch(
209209
getter = () => source.value
210210
forceTrigger = isShallow(source)
211211
} else if (isReactive(source)) {
212-
getter = () => source
213-
deep = true
212+
deep = isShallow(source) ? false : deep ?? true
213+
getter = deep ? () => source : () => shallowTraverse(source)
214+
forceTrigger = true
214215
} else if (isArray(source)) {
215216
isMultiSource = true
216217
forceTrigger = source.some(s => isReactive(s) || isShallow(s))
@@ -464,3 +465,23 @@ export function traverse(value: unknown, seen?: Set<unknown>) {
464465
}
465466
return value
466467
}
468+
469+
export function shallowTraverse(value: unknown) {
470+
if (!isObject(value) || (value as any)[ReactiveFlags.SKIP]) {
471+
return value
472+
}
473+
if (isArray(value)) {
474+
for (let i = 0; i < value.length; i++) {
475+
value[i]
476+
}
477+
} else if (isSet(value) || isMap(value)) {
478+
value.forEach((v: any) => {
479+
v
480+
})
481+
} else if (isPlainObject(value)) {
482+
for (const key in value) {
483+
value[key]
484+
}
485+
}
486+
return value
487+
}

0 commit comments

Comments
 (0)