fix(reactivity): `triggerRef` working with `toRef` from reactive (#7507)

* fix(reactivity): `triggerRef` working with `toRef` from reactive

* chore: refactor
This commit is contained in:
Anthony Fu 2023-02-01 09:20:47 +01:00 committed by GitHub
parent 5f1883ec53
commit e64c9ae957
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 4 deletions

View File

@ -377,3 +377,7 @@ function triggerEffect(
}
}
}
export function getDepFromReactive(object: any, key: string | number | symbol) {
return targetMap.get(object)?.get(key)
}

View 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>>

View 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()