diff --git a/packages/reactivity/__tests__/ref.spec.ts b/packages/reactivity/__tests__/ref.spec.ts index 5126982..fa8f954 100644 --- a/packages/reactivity/__tests__/ref.spec.ts +++ b/packages/reactivity/__tests__/ref.spec.ts @@ -68,4 +68,16 @@ describe("ref", () => { expect(unRef(a)).toBe(1); expect(unRef(1)).toBe(1); }); + + it('should automatically dereference reactive properties with proxyRefs', () => { + const user = { + age: ref(10), + name: 'xiaohong' + } + const original = reactive(user) + const proxyUser = proxyRefs(original) + + expect(proxyUser).toBe(original) + expect(proxyUser.age).toBe(10) + }) }); diff --git a/packages/reactivity/src/baseHandlers.ts b/packages/reactivity/src/baseHandlers.ts index 2bb7ed7..6277e11 100644 --- a/packages/reactivity/src/baseHandlers.ts +++ b/packages/reactivity/src/baseHandlers.ts @@ -8,6 +8,7 @@ import { shallowReadonlyMap, } from "./reactive"; import { isObject } from "@mini-vue/shared"; +import { isRef } from "./ref"; const get = createGetter(); const set = createSetter(); @@ -52,6 +53,11 @@ function createGetter(isReadonly = false, shallow = false) { return res; } + // 当访问的值是 ref 时,返回 .value + if(isRef(res)) { + return res.value + } + if (isObject(res)) { // 把内部所有的是 object 的值都用 reactive 包裹,变成响应式对象 // 如果说这个 res 值是一个对象的话,那么我们需要把获取到的 res 也转换成 reactive diff --git a/packages/reactivity/src/ref.ts b/packages/reactivity/src/ref.ts index 523b35a..4b606b4 100644 --- a/packages/reactivity/src/ref.ts +++ b/packages/reactivity/src/ref.ts @@ -1,7 +1,7 @@ import { trackEffects, triggerEffects, isTracking } from "./effect"; import { createDep } from "./dep"; import { isObject, hasChanged } from "@mini-vue/shared"; -import { reactive } from "./reactive"; +import { isReactive, reactive } from "./reactive"; export class RefImpl { private _rawValue: any; @@ -82,11 +82,14 @@ const shallowUnwrapHandlers = { }, }; -// 这里没有处理 objectWithRefs 是 reactive 类型的时候 -// TODO reactive 里面如果有 ref 类型的 key 的话, 那么也是不需要调用 ref.value 的 -// (but 这个逻辑在 reactive 里面没有实现) +// 当传入的值是reactive时,直接返回 +// 其他情况下,使用 proxy 来处理 export function proxyRefs(objectWithRefs) { - return new Proxy(objectWithRefs, shallowUnwrapHandlers); + if(isReactive(objectWithRefs)){ + return objectWithRefs + }else{ + return new Proxy(objectWithRefs, shallowUnwrapHandlers); + } } // 把 ref 里面的值拿到 @@ -95,5 +98,5 @@ export function unRef(ref) { } export function isRef(value) { - return !!value.__v_isRef; + return !!(value && value.__v_isRef === true); }