mirror of https://github.com/vuejs/core.git
fix(reactivity): `triggerRef` working with `toRef` from reactive (#7507)
* fix(reactivity): `triggerRef` working with `toRef` from reactive * chore: refactor
This commit is contained in:
parent
5f1883ec53
commit
e64c9ae957
|
@ -377,3 +377,7 @@ function triggerEffect(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getDepFromReactive(object: any, key: string | number | symbol) {
|
||||||
|
return targetMap.get(object)?.get(key)
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {
|
import {
|
||||||
activeEffect,
|
activeEffect,
|
||||||
|
getDepFromReactive,
|
||||||
shouldTrack,
|
shouldTrack,
|
||||||
trackEffects,
|
trackEffects,
|
||||||
triggerEffects
|
triggerEffects
|
||||||
|
@ -53,16 +54,17 @@ export function trackRefValue(ref: RefBase<any>) {
|
||||||
|
|
||||||
export function triggerRefValue(ref: RefBase<any>, newVal?: any) {
|
export function triggerRefValue(ref: RefBase<any>, newVal?: any) {
|
||||||
ref = toRaw(ref)
|
ref = toRaw(ref)
|
||||||
if (ref.dep) {
|
const dep = ref.dep
|
||||||
|
if (dep) {
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
triggerEffects(ref.dep, {
|
triggerEffects(dep, {
|
||||||
target: ref,
|
target: ref,
|
||||||
type: TriggerOpTypes.SET,
|
type: TriggerOpTypes.SET,
|
||||||
key: 'value',
|
key: 'value',
|
||||||
newValue: newVal
|
newValue: newVal
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
triggerEffects(ref.dep)
|
triggerEffects(dep)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,6 +230,10 @@ class ObjectRefImpl<T extends object, K extends keyof T> {
|
||||||
set value(newVal) {
|
set value(newVal) {
|
||||||
this._object[this._key] = 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>>
|
export type ToRef<T> = IfAny<T, Ref<T>, [T] extends [Ref] ? T : Ref<T>>
|
||||||
|
|
|
@ -30,7 +30,8 @@ import {
|
||||||
triggerRef,
|
triggerRef,
|
||||||
shallowRef,
|
shallowRef,
|
||||||
Ref,
|
Ref,
|
||||||
effectScope
|
effectScope,
|
||||||
|
toRef
|
||||||
} from '@vue/reactivity'
|
} from '@vue/reactivity'
|
||||||
|
|
||||||
// reference: https://vue-composition-api-rfc.netlify.com/api.html#watch
|
// reference: https://vue-composition-api-rfc.netlify.com/api.html#watch
|
||||||
|
@ -926,6 +927,25 @@ describe('api: watch', () => {
|
||||||
expect(spy).toHaveBeenCalledTimes(1)
|
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
|
// #2125
|
||||||
test('watchEffect should not recursively trigger itself', async () => {
|
test('watchEffect should not recursively trigger itself', async () => {
|
||||||
const spy = vi.fn()
|
const spy = vi.fn()
|
||||||
|
|
Loading…
Reference in New Issue