]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(reactivity): `triggerRef` working with `toRef` from reactive (#7507)
authorAnthony Fu <anthonyfu117@hotmail.com>
Wed, 1 Feb 2023 08:20:47 +0000 (09:20 +0100)
committerGitHub <noreply@github.com>
Wed, 1 Feb 2023 08:20:47 +0000 (03:20 -0500)
* fix(reactivity): `triggerRef` working with `toRef` from reactive

* chore: refactor

packages/reactivity/src/effect.ts
packages/reactivity/src/ref.ts
packages/runtime-core/__tests__/apiWatch.spec.ts

index 9ef38c1b0655a597a3cb7e687f88fcc55c72242b..5eb84bc48d70977f88edecf75706f2282525a80f 100644 (file)
@@ -377,3 +377,7 @@ function triggerEffect(
     }
   }
 }
+
+export function getDepFromReactive(object: any, key: string | number | symbol) {
+  return targetMap.get(object)?.get(key)
+}
index 26c6fe192baeb9267ddabab4dbd94c89eacf7da6..124e2aaa869a0760e6cd18696514eaff6cf6d7e5 100644 (file)
@@ -1,5 +1,6 @@
 import {
   activeEffect,
+  getDepFromReactive,
   shouldTrack,
   trackEffects,
   triggerEffects
@@ -53,16 +54,17 @@ export function trackRefValue(ref: RefBase<any>) {
 
 export function triggerRefValue(ref: RefBase<any>, newVal?: any) {
   ref = toRaw(ref)
-  if (ref.dep) {
+  const dep = ref.dep
+  if (dep) {
     if (__DEV__) {
-      triggerEffects(ref.dep, {
+      triggerEffects(dep, {
         target: ref,
         type: TriggerOpTypes.SET,
         key: 'value',
         newValue: newVal
       })
     } else {
-      triggerEffects(ref.dep)
+      triggerEffects(dep)
     }
   }
 }
@@ -228,6 +230,10 @@ class ObjectRefImpl<T extends object, K extends keyof T> {
   set value(newVal) {
     this._object[this._key] = newVal
   }
+
+  get dep(): Dep | undefined {
+    return getDepFromReactive(toRaw(this._object), this._key)
+  }
 }
 
 export type ToRef<T> = IfAny<T, Ref<T>, [T] extends [Ref] ? T : Ref<T>>
index b9670820cd964f76ae8f79caa0047aa1ef510a81..73fe02cc8fab053cf2b9ea2f8cb03ebbf48ad281 100644 (file)
@@ -30,7 +30,8 @@ import {
   triggerRef,
   shallowRef,
   Ref,
-  effectScope
+  effectScope,
+  toRef
 } from '@vue/reactivity'
 
 // reference: https://vue-composition-api-rfc.netlify.com/api.html#watch
@@ -926,6 +927,25 @@ describe('api: watch', () => {
     expect(spy).toHaveBeenCalledTimes(1)
   })
 
+  test('should force trigger on triggerRef with toRef from reactive', async () => {
+    const foo = reactive({ bar: 1 })
+    const bar = toRef(foo, 'bar')
+    const spy = jest.fn()
+
+    watchEffect(() => {
+      bar.value
+      spy()
+    })
+
+    expect(spy).toHaveBeenCalledTimes(1)
+
+    triggerRef(bar)
+
+    await nextTick()
+    // should trigger now
+    expect(spy).toHaveBeenCalledTimes(2)
+  })
+
   // #2125
   test('watchEffect should not recursively trigger itself', async () => {
     const spy = vi.fn()