feat(reactivity): proxyRefs
method and ShallowUnwrapRefs
type (#1682)
* feat(reactivity): `proxyRefs` method and `ShallowUnwrapRefs` type BREAKING CHANGE: template auto ref unwrapping are now applied shallowly, i.e. only at the root level. See https://github.com/vuejs/vue-next/pull/1682 for more details.
This commit is contained in:
parent
de62cc040c
commit
aa06b1034d
@ -1,15 +1,17 @@
|
||||
export {
|
||||
ref,
|
||||
unref,
|
||||
shallowRef,
|
||||
isRef,
|
||||
toRef,
|
||||
toRefs,
|
||||
unref,
|
||||
proxyRefs,
|
||||
customRef,
|
||||
triggerRef,
|
||||
Ref,
|
||||
UnwrapRef,
|
||||
ToRefs,
|
||||
UnwrapRef,
|
||||
ShallowUnwrapRef,
|
||||
RefUnwrapBailTypes
|
||||
} from './ref'
|
||||
export {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { track, trigger } from './effect'
|
||||
import { TrackOpTypes, TriggerOpTypes } from './operations'
|
||||
import { isObject, hasChanged } from '@vue/shared'
|
||||
import { reactive, isProxy, toRaw } from './reactive'
|
||||
import { reactive, isProxy, toRaw, isReactive } from './reactive'
|
||||
import { CollectionTypes } from './collectionHandlers'
|
||||
|
||||
declare const RefSymbol: unique symbol
|
||||
@ -71,6 +71,27 @@ export function unref<T>(ref: T): T extends Ref<infer V> ? V : T {
|
||||
return isRef(ref) ? (ref.value as any) : ref
|
||||
}
|
||||
|
||||
const shallowUnwrapHandlers: ProxyHandler<any> = {
|
||||
get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
|
||||
set: (target, key, value, receiver) => {
|
||||
const oldValue = target[key]
|
||||
if (isRef(oldValue) && !isRef(value)) {
|
||||
oldValue.value = value
|
||||
return true
|
||||
} else {
|
||||
return Reflect.set(target, key, value, receiver)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function proxyRefs<T extends object>(
|
||||
objectWithRefs: T
|
||||
): ShallowUnwrapRef<T> {
|
||||
return isReactive(objectWithRefs)
|
||||
? objectWithRefs
|
||||
: new Proxy(objectWithRefs, shallowUnwrapHandlers)
|
||||
}
|
||||
|
||||
export type CustomRefFactory<T> = (
|
||||
track: () => void,
|
||||
trigger: () => void
|
||||
@ -146,6 +167,10 @@ type BaseTypes = string | number | boolean
|
||||
*/
|
||||
export interface RefUnwrapBailTypes {}
|
||||
|
||||
export type ShallowUnwrapRef<T> = {
|
||||
[K in keyof T]: T[K] extends Ref<infer V> ? V : T[K]
|
||||
}
|
||||
|
||||
export type UnwrapRef<T> = T extends Ref<infer V>
|
||||
? UnwrapRefSimple<V>
|
||||
: UnwrapRefSimple<T>
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { VNode, VNodeChild, isVNode } from './vnode'
|
||||
import {
|
||||
reactive,
|
||||
ReactiveEffect,
|
||||
pauseTracking,
|
||||
resetTracking,
|
||||
shallowReadonly
|
||||
shallowReadonly,
|
||||
proxyRefs
|
||||
} from '@vue/reactivity'
|
||||
import {
|
||||
CreateComponentPublicInstance,
|
||||
@ -548,7 +548,7 @@ export function handleSetupResult(
|
||||
}
|
||||
// setup returned bindings.
|
||||
// assuming a render function compiled from template is present.
|
||||
instance.setupState = reactive(setupResult)
|
||||
instance.setupState = proxyRefs(setupResult)
|
||||
if (__DEV__) {
|
||||
exposeSetupStateOnRenderContext(instance)
|
||||
}
|
||||
|
@ -10,12 +10,12 @@ import {
|
||||
} from '@vue/shared'
|
||||
import {
|
||||
ReactiveEffect,
|
||||
UnwrapRef,
|
||||
toRaw,
|
||||
shallowReadonly,
|
||||
ReactiveFlags,
|
||||
track,
|
||||
TrackOpTypes
|
||||
TrackOpTypes,
|
||||
ShallowUnwrapRef
|
||||
} from '@vue/reactivity'
|
||||
import {
|
||||
ExtractComputedReturns,
|
||||
@ -154,7 +154,7 @@ export type ComponentPublicInstance<
|
||||
$nextTick: typeof nextTick
|
||||
$watch: typeof instanceWatch
|
||||
} & P &
|
||||
UnwrapRef<B> &
|
||||
ShallowUnwrapRef<B> &
|
||||
D &
|
||||
ExtractComputedReturns<C> &
|
||||
M &
|
||||
|
@ -8,6 +8,7 @@ export {
|
||||
readonly,
|
||||
// utilities
|
||||
unref,
|
||||
proxyRefs,
|
||||
isRef,
|
||||
toRef,
|
||||
toRefs,
|
||||
@ -125,6 +126,7 @@ export {
|
||||
ComputedRef,
|
||||
WritableComputedRef,
|
||||
UnwrapRef,
|
||||
ShallowUnwrapRef,
|
||||
WritableComputedOptions,
|
||||
ToRefs,
|
||||
DeepReadonly
|
||||
|
@ -146,7 +146,7 @@ describe('with object props', () => {
|
||||
|
||||
// assert setup context unwrapping
|
||||
expectType<number>(this.c)
|
||||
expectType<string>(this.d.e)
|
||||
expectType<string>(this.d.e.value)
|
||||
expectType<GT>(this.f.g)
|
||||
|
||||
// setup context properties should be mutable
|
||||
|
Loading…
Reference in New Issue
Block a user