From e7300eb47960a153311d568d7976ac5256eb6297 Mon Sep 17 00:00:00 2001 From: AbaAba~ <35401154+Kingbultsea@users.noreply.github.com> Date: Sat, 8 May 2021 06:03:35 +0800 Subject: [PATCH] fix(runtime-core): watching multiple sources: computed (#3066) fix #3068 --- .../runtime-core/__tests__/apiWatch.spec.ts | 24 +++++++++++++++++++ packages/runtime-core/src/apiWatch.ts | 12 ++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/packages/runtime-core/__tests__/apiWatch.spec.ts b/packages/runtime-core/__tests__/apiWatch.spec.ts index 0c3719e7364..aed7d65b6a5 100644 --- a/packages/runtime-core/__tests__/apiWatch.spec.ts +++ b/packages/runtime-core/__tests__/apiWatch.spec.ts @@ -944,4 +944,28 @@ describe('api: watch', () => { await nextTick() expect(spy).toHaveBeenCalledTimes(2) }) + + it('watching sources: ref', async () => { + const foo = ref([1]) + const spy = jest.fn() + watch(foo, () => { + spy() + }) + foo.value = foo.value.slice() + await nextTick() + expect(spy).toBeCalledTimes(1) + }) + + it('watching multiple sources: computed', async () => { + let count = 0 + const value = ref('1') + const plus = computed(() => !!value.value) + watch([plus], () => { + count++ + }) + value.value = '2' + await nextTick() + expect(plus.value).toBe(true) + expect(count).toBe(0) + }) }) diff --git a/packages/runtime-core/src/apiWatch.ts b/packages/runtime-core/src/apiWatch.ts index fa476f15dae..41ded87847a 100644 --- a/packages/runtime-core/src/apiWatch.ts +++ b/packages/runtime-core/src/apiWatch.ts @@ -171,6 +171,8 @@ function doWatch( let getter: () => any let forceTrigger = false + let isMultiSource = false + if (isRef(source)) { getter = () => (source as Ref).value forceTrigger = !!(source as Ref)._shallow @@ -178,6 +180,8 @@ function doWatch( getter = () => source deep = true } else if (isArray(source)) { + isMultiSource = true + forceTrigger = source.some(isReactive) getter = () => source.map(s => { if (isRef(s)) { @@ -265,7 +269,7 @@ function doWatch( return NOOP } - let oldValue = isArray(source) ? [] : INITIAL_WATCHER_VALUE + let oldValue = isMultiSource ? [] : INITIAL_WATCHER_VALUE const job: SchedulerJob = () => { if (!runner.active) { return @@ -276,7 +280,11 @@ function doWatch( if ( deep || forceTrigger || - hasChanged(newValue, oldValue) || + (isMultiSource + ? (newValue as any[]).some((v, i) => + hasChanged(v, (oldValue as any[])[i]) + ) + : hasChanged(newValue, oldValue)) || (__COMPAT__ && isArray(newValue) && isCompatEnabled(DeprecationTypes.WATCH_ARRAY, instance))