实现 proxyRefs 功能

什么是proxyRefs?有什么作用?
proxyRefs 主要用来在vue3中 template 的 setup 去转换一下ref类型,省去了 .value 繁琐操作。
本质就是一个proxy,代理了一个取值,修改的功能,取值功能就是一个unRef,修改的时候,需要判断被修改属性是否是ref类型,如果是ref类型,且新值为非ref类型就是 替换掉被修改属性的 .value;如果被修改属性和新值都为ref类型,则直接替换掉被修改属性即可。

接下来实现一下这个功能,还是熟悉的TDD

ref.spec.ts

import { effect } from "../src/effect";
import { reactive } from "../src/reactive";
import { isRef, proxyRefs, ref, unRef } from "../src/ref";

describe("ref", () => {
  ...
  it("proxyRefs", () => {
    const user = {
      age: ref(10),
      name: "xiaoming",
    };

    // 用在vue3 template 中 setup 返回出去时调用了,在大胡子里不用 .value 去获取值
    const proxyUser = proxyRefs(user);
    expect(proxyUser.age).toBe(10);
    expect(user.age.value).toBe(10);
    expect(proxyUser.name).toBe("xiaoming");

    // 如果 set 的值是非响应式,就是替换;如果是响应式,就是重新赋值
    proxyUser.age = 20;
    expect(proxyUser.age).toBe(20);
    expect(user.age.value).toBe(20);

    proxyUser.age = ref(10);
    expect(proxyUser.age).toBe(10);
    expect(user.age.value).toBe(10);
  });
});

ref.ts

...
export function proxyRefs(objectWithRefs) {
  return new Proxy(objectWithRefs, {
    get(target, key) {
      return unRef(target[key]);
    },
    set(target, key, value) {
      // 当被修改的属性是 ref 类型,且value 不是 ref 类型就是替换掉被修改的 .value 值
      // 否则,被修改属性和value 都是 ref 类型,直接替换成value即可
      if (isRef(target[key]) && !isRef(value)) {
        return (target[key].value = value);
      } else {
        return Reflect.set(target, key, value);
      }
    },
  });
}

好了,执行测试,完美收官。

最后

附上git代码地址:mini-vue,欢迎大家踊跃探讨,如果可以的话,帮忙一键三连,点点 git star,万分感谢!

Logo

前往低代码交流专区

更多推荐