Skip to content

Commit e7300eb

Browse files
authored
fix(runtime-core): watching multiple sources: computed (#3066)
fix #3068
1 parent 349eb0f commit e7300eb

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

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

+24
Original file line numberDiff line numberDiff line change
@@ -944,4 +944,28 @@ describe('api: watch', () => {
944944
await nextTick()
945945
expect(spy).toHaveBeenCalledTimes(2)
946946
})
947+
948+
it('watching sources: ref<any[]>', async () => {
949+
const foo = ref([1])
950+
const spy = jest.fn()
951+
watch(foo, () => {
952+
spy()
953+
})
954+
foo.value = foo.value.slice()
955+
await nextTick()
956+
expect(spy).toBeCalledTimes(1)
957+
})
958+
959+
it('watching multiple sources: computed', async () => {
960+
let count = 0
961+
const value = ref('1')
962+
const plus = computed(() => !!value.value)
963+
watch([plus], () => {
964+
count++
965+
})
966+
value.value = '2'
967+
await nextTick()
968+
expect(plus.value).toBe(true)
969+
expect(count).toBe(0)
970+
})
947971
})

packages/runtime-core/src/apiWatch.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,17 @@ function doWatch(
171171

172172
let getter: () => any
173173
let forceTrigger = false
174+
let isMultiSource = false
175+
174176
if (isRef(source)) {
175177
getter = () => (source as Ref).value
176178
forceTrigger = !!(source as Ref)._shallow
177179
} else if (isReactive(source)) {
178180
getter = () => source
179181
deep = true
180182
} else if (isArray(source)) {
183+
isMultiSource = true
184+
forceTrigger = source.some(isReactive)
181185
getter = () =>
182186
source.map(s => {
183187
if (isRef(s)) {
@@ -265,7 +269,7 @@ function doWatch(
265269
return NOOP
266270
}
267271

268-
let oldValue = isArray(source) ? [] : INITIAL_WATCHER_VALUE
272+
let oldValue = isMultiSource ? [] : INITIAL_WATCHER_VALUE
269273
const job: SchedulerJob = () => {
270274
if (!runner.active) {
271275
return
@@ -276,7 +280,11 @@ function doWatch(
276280
if (
277281
deep ||
278282
forceTrigger ||
279-
hasChanged(newValue, oldValue) ||
283+
(isMultiSource
284+
? (newValue as any[]).some((v, i) =>
285+
hasChanged(v, (oldValue as any[])[i])
286+
)
287+
: hasChanged(newValue, oldValue)) ||
280288
(__COMPAT__ &&
281289
isArray(newValue) &&
282290
isCompatEnabled(DeprecationTypes.WATCH_ARRAY, instance))

0 commit comments

Comments
 (0)