From fce2689ff1af0b632a2034403a6dfbcbff91aa60 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 30 Jul 2020 18:29:38 -0400 Subject: [PATCH] fix(watch): should trigger watcher callback on triggerRef when watching ref source fix #1736 --- .../runtime-core/__tests__/apiWatch.spec.ts | 26 ++++++++++++++++++- packages/runtime-core/src/apiWatch.ts | 7 ++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/packages/runtime-core/__tests__/apiWatch.spec.ts b/packages/runtime-core/__tests__/apiWatch.spec.ts index 951f2ba0ab5..97f686ad995 100644 --- a/packages/runtime-core/__tests__/apiWatch.spec.ts +++ b/packages/runtime-core/__tests__/apiWatch.spec.ts @@ -12,7 +12,8 @@ import { ITERATE_KEY, DebuggerEvent, TrackOpTypes, - TriggerOpTypes + TriggerOpTypes, + triggerRef } from '@vue/reactivity' // reference: https://vue-composition-api-rfc.netlify.com/api.html#watch @@ -637,4 +638,27 @@ describe('api: watch', () => { v.value++ expect(calls).toBe(1) }) + + test('should force trigger on triggerRef when watching a ref', async () => { + const v = ref({ a: 1 }) + let sideEffect = 0 + watch(v, obj => { + sideEffect = obj.a + }) + + v.value = v.value + await nextTick() + // should not trigger + expect(sideEffect).toBe(0) + + v.value.a++ + await nextTick() + // should not trigger + expect(sideEffect).toBe(0) + + triggerRef(v) + await nextTick() + // should trigger now + expect(sideEffect).toBe(2) + }) }) diff --git a/packages/runtime-core/src/apiWatch.ts b/packages/runtime-core/src/apiWatch.ts index 15c9e3e5000..1e639d25b89 100644 --- a/packages/runtime-core/src/apiWatch.ts +++ b/packages/runtime-core/src/apiWatch.ts @@ -159,8 +159,9 @@ function doWatch( } let getter: () => any - if (isRef(source)) { - getter = () => source.value + const isRefSource = isRef(source) + if (isRefSource) { + getter = () => (source as Ref).value } else if (isReactive(source)) { getter = () => source deep = true @@ -239,7 +240,7 @@ function doWatch( if (cb) { // watch(source, cb) const newValue = runner() - if (deep || hasChanged(newValue, oldValue)) { + if (deep || isRefSource || hasChanged(newValue, oldValue)) { // cleanup before running cb again if (cleanup) { cleanup()