]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(reactivity): ref(Ref) should return Ref (#180)
author相学长 <75851654@qq.com>
Thu, 10 Oct 2019 15:34:42 +0000 (23:34 +0800)
committerEvan You <yyx990803@gmail.com>
Thu, 10 Oct 2019 15:34:42 +0000 (11:34 -0400)
packages/reactivity/__tests__/reactive.spec.ts
packages/reactivity/__tests__/ref.spec.ts
packages/reactivity/src/computed.ts
packages/reactivity/src/ref.ts

index ebeac774d56e576b747b76052e9c27590bc1955e..8743d78c881cebe5aabb22d4027fcc47a51d417e 100644 (file)
@@ -1,3 +1,4 @@
+import { ref, isRef } from '../src/ref'
 import { reactive, isReactive, toRaw, markNonReactive } from '../src/reactive'
 import { mockWarn } from '@vue/runtime-test'
 
@@ -126,6 +127,14 @@ describe('reactivity/reactive', () => {
     expect(toRaw(original)).toBe(original)
   })
 
+  test('should not unwrap Ref<T>', () => {
+    const observedNumberRef = reactive(ref(1))
+    const observedObjectRef = reactive(ref({ foo: 1 }))
+
+    expect(isRef(observedNumberRef)).toBe(true)
+    expect(isRef(observedObjectRef)).toBe(true)
+  })
+
   test('non-observable values', () => {
     const assertValue = (value: any) => {
       reactive(value)
index dd04ac6a5ce35e73968efdd1da7339d38d2e0590..f2f02e10470f11399590a705d76ca03f34db842a 100644 (file)
@@ -63,6 +63,13 @@ describe('reactivity/ref', () => {
     expect(dummy3).toBe(3)
   })
 
+  it('should unwrap nested ref in types', () => {
+    const a = ref(0)
+    const b = ref(a)
+
+    expect(typeof (b.value + 1)).toBe('number')
+  })
+
   it('should unwrap nested values in types', () => {
     const a = {
       b: ref(0)
index c1cf34cbb93c200968ff4cbcdb09b424681dc2c7..dcc1d4a42c85baa95af07e875c87ff67eccc4981 100644 (file)
@@ -1,9 +1,9 @@
 import { effect, ReactiveEffect, activeReactiveEffectStack } from './effect'
-import { Ref, refSymbol, UnwrapNestedRefs } from './ref'
+import { Ref, refSymbol, UnwrapRef } from './ref'
 import { isFunction, NOOP } from '@vue/shared'
 
 export interface ComputedRef<T> extends WritableComputedRef<T> {
-  readonly value: UnwrapNestedRefs<T>
+  readonly value: UnwrapRef<T>
 }
 
 export interface WritableComputedRef<T> extends Ref<T> {
index 9e000d979ae5e4a2936978ae17ff6c43ab00c267..5aac9272bfb4f353e801645e5d1ae8ad9cae95c4 100644 (file)
@@ -7,14 +7,15 @@ export const refSymbol = Symbol(__DEV__ ? 'refSymbol' : undefined)
 
 export interface Ref<T = any> {
   [refSymbol]: true
-  value: UnwrapNestedRefs<T>
+  value: UnwrapRef<T>
 }
 
-export type UnwrapNestedRefs<T> = T extends Ref ? T : UnwrapRef<T>
-
 const convert = (val: any): any => (isObject(val) ? reactive(val) : val)
 
 export function ref<T>(raw: T): Ref<T> {
+  if (isRef(raw)) {
+    return raw
+  }
   raw = convert(raw)
   const v = {
     [refSymbol]: true,
@@ -48,16 +49,15 @@ function toProxyRef<T extends object, K extends keyof T>(
   object: T,
   key: K
 ): Ref<T[K]> {
-  const v = {
+  return {
     [refSymbol]: true,
-    get value() {
+    get value(): any {
       return object[key]
     },
     set value(newVal) {
       object[key] = newVal
     }
   }
-  return v as Ref<T[K]>
 }
 
 type BailTypes =
@@ -80,3 +80,6 @@ export type UnwrapRef<T> = {
     : T extends BailTypes
       ? 'stop' // bail out on types that shouldn't be unwrapped
       : T extends object ? 'object' : 'stop']
+
+// only unwrap nested ref
+export type UnwrapNestedRefs<T> = T extends Ref ? T : UnwrapRef<T>