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 {
 | 
					export {
 | 
				
			||||||
  ref,
 | 
					  ref,
 | 
				
			||||||
  unref,
 | 
					 | 
				
			||||||
  shallowRef,
 | 
					  shallowRef,
 | 
				
			||||||
  isRef,
 | 
					  isRef,
 | 
				
			||||||
  toRef,
 | 
					  toRef,
 | 
				
			||||||
  toRefs,
 | 
					  toRefs,
 | 
				
			||||||
 | 
					  unref,
 | 
				
			||||||
 | 
					  proxyRefs,
 | 
				
			||||||
  customRef,
 | 
					  customRef,
 | 
				
			||||||
  triggerRef,
 | 
					  triggerRef,
 | 
				
			||||||
  Ref,
 | 
					  Ref,
 | 
				
			||||||
  UnwrapRef,
 | 
					 | 
				
			||||||
  ToRefs,
 | 
					  ToRefs,
 | 
				
			||||||
 | 
					  UnwrapRef,
 | 
				
			||||||
 | 
					  ShallowUnwrapRef,
 | 
				
			||||||
  RefUnwrapBailTypes
 | 
					  RefUnwrapBailTypes
 | 
				
			||||||
} from './ref'
 | 
					} from './ref'
 | 
				
			||||||
export {
 | 
					export {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
import { track, trigger } from './effect'
 | 
					import { track, trigger } from './effect'
 | 
				
			||||||
import { TrackOpTypes, TriggerOpTypes } from './operations'
 | 
					import { TrackOpTypes, TriggerOpTypes } from './operations'
 | 
				
			||||||
import { isObject, hasChanged } from '@vue/shared'
 | 
					import { isObject, hasChanged } from '@vue/shared'
 | 
				
			||||||
import { reactive, isProxy, toRaw } from './reactive'
 | 
					import { reactive, isProxy, toRaw, isReactive } from './reactive'
 | 
				
			||||||
import { CollectionTypes } from './collectionHandlers'
 | 
					import { CollectionTypes } from './collectionHandlers'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
declare const RefSymbol: unique symbol
 | 
					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
 | 
					  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> = (
 | 
					export type CustomRefFactory<T> = (
 | 
				
			||||||
  track: () => void,
 | 
					  track: () => void,
 | 
				
			||||||
  trigger: () => void
 | 
					  trigger: () => void
 | 
				
			||||||
@ -146,6 +167,10 @@ type BaseTypes = string | number | boolean
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
export interface RefUnwrapBailTypes {}
 | 
					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>
 | 
					export type UnwrapRef<T> = T extends Ref<infer V>
 | 
				
			||||||
  ? UnwrapRefSimple<V>
 | 
					  ? UnwrapRefSimple<V>
 | 
				
			||||||
  : UnwrapRefSimple<T>
 | 
					  : UnwrapRefSimple<T>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,10 @@
 | 
				
			|||||||
import { VNode, VNodeChild, isVNode } from './vnode'
 | 
					import { VNode, VNodeChild, isVNode } from './vnode'
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  reactive,
 | 
					 | 
				
			||||||
  ReactiveEffect,
 | 
					  ReactiveEffect,
 | 
				
			||||||
  pauseTracking,
 | 
					  pauseTracking,
 | 
				
			||||||
  resetTracking,
 | 
					  resetTracking,
 | 
				
			||||||
  shallowReadonly
 | 
					  shallowReadonly,
 | 
				
			||||||
 | 
					  proxyRefs
 | 
				
			||||||
} from '@vue/reactivity'
 | 
					} from '@vue/reactivity'
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  CreateComponentPublicInstance,
 | 
					  CreateComponentPublicInstance,
 | 
				
			||||||
@ -548,7 +548,7 @@ export function handleSetupResult(
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    // setup returned bindings.
 | 
					    // setup returned bindings.
 | 
				
			||||||
    // assuming a render function compiled from template is present.
 | 
					    // assuming a render function compiled from template is present.
 | 
				
			||||||
    instance.setupState = reactive(setupResult)
 | 
					    instance.setupState = proxyRefs(setupResult)
 | 
				
			||||||
    if (__DEV__) {
 | 
					    if (__DEV__) {
 | 
				
			||||||
      exposeSetupStateOnRenderContext(instance)
 | 
					      exposeSetupStateOnRenderContext(instance)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -10,12 +10,12 @@ import {
 | 
				
			|||||||
} from '@vue/shared'
 | 
					} from '@vue/shared'
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  ReactiveEffect,
 | 
					  ReactiveEffect,
 | 
				
			||||||
  UnwrapRef,
 | 
					 | 
				
			||||||
  toRaw,
 | 
					  toRaw,
 | 
				
			||||||
  shallowReadonly,
 | 
					  shallowReadonly,
 | 
				
			||||||
  ReactiveFlags,
 | 
					  ReactiveFlags,
 | 
				
			||||||
  track,
 | 
					  track,
 | 
				
			||||||
  TrackOpTypes
 | 
					  TrackOpTypes,
 | 
				
			||||||
 | 
					  ShallowUnwrapRef
 | 
				
			||||||
} from '@vue/reactivity'
 | 
					} from '@vue/reactivity'
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  ExtractComputedReturns,
 | 
					  ExtractComputedReturns,
 | 
				
			||||||
@ -154,7 +154,7 @@ export type ComponentPublicInstance<
 | 
				
			|||||||
  $nextTick: typeof nextTick
 | 
					  $nextTick: typeof nextTick
 | 
				
			||||||
  $watch: typeof instanceWatch
 | 
					  $watch: typeof instanceWatch
 | 
				
			||||||
} & P &
 | 
					} & P &
 | 
				
			||||||
  UnwrapRef<B> &
 | 
					  ShallowUnwrapRef<B> &
 | 
				
			||||||
  D &
 | 
					  D &
 | 
				
			||||||
  ExtractComputedReturns<C> &
 | 
					  ExtractComputedReturns<C> &
 | 
				
			||||||
  M &
 | 
					  M &
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,7 @@ export {
 | 
				
			|||||||
  readonly,
 | 
					  readonly,
 | 
				
			||||||
  // utilities
 | 
					  // utilities
 | 
				
			||||||
  unref,
 | 
					  unref,
 | 
				
			||||||
 | 
					  proxyRefs,
 | 
				
			||||||
  isRef,
 | 
					  isRef,
 | 
				
			||||||
  toRef,
 | 
					  toRef,
 | 
				
			||||||
  toRefs,
 | 
					  toRefs,
 | 
				
			||||||
@ -125,6 +126,7 @@ export {
 | 
				
			|||||||
  ComputedRef,
 | 
					  ComputedRef,
 | 
				
			||||||
  WritableComputedRef,
 | 
					  WritableComputedRef,
 | 
				
			||||||
  UnwrapRef,
 | 
					  UnwrapRef,
 | 
				
			||||||
 | 
					  ShallowUnwrapRef,
 | 
				
			||||||
  WritableComputedOptions,
 | 
					  WritableComputedOptions,
 | 
				
			||||||
  ToRefs,
 | 
					  ToRefs,
 | 
				
			||||||
  DeepReadonly
 | 
					  DeepReadonly
 | 
				
			||||||
 | 
				
			|||||||
@ -146,7 +146,7 @@ describe('with object props', () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      // assert setup context unwrapping
 | 
					      // assert setup context unwrapping
 | 
				
			||||||
      expectType<number>(this.c)
 | 
					      expectType<number>(this.c)
 | 
				
			||||||
      expectType<string>(this.d.e)
 | 
					      expectType<string>(this.d.e.value)
 | 
				
			||||||
      expectType<GT>(this.f.g)
 | 
					      expectType<GT>(this.f.g)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // setup context properties should be mutable
 | 
					      // setup context properties should be mutable
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user