13_实现isRef和unRef功能

168 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第14天,点击查看活动详情

13_实现isRef和unRef功能

🙋 Hello,I'm IamZJT!
✍️ 一名菜鸟前端开发工程师!

📦 Github项目地址:zjt-mini-vue3
🖐️ 欢迎 点赞 star,期盼与您并肩前行...

一、实现isRef

(一)单元测试

// src/reactivity/reactive.ts

it('isRef', function () {
  const a = ref(1);
  const user = reactive({
    age: 1
  });

  expect(isRef(a)).toBe(true);
  expect(isRef(1)).toBe(false);
  expect(isRef(user)).toBe(false);
});

先来看一下单测,isRef的功能就是判断一个变量是不是一个ref响应式变量。

(二)代码实现

实现起来也没什么难度,跟之前一样,在初始化的时候,给它一个标识:__v_isRef,默认为true。

// src/reactivity/ref.ts

class RefImpl {
  private _value: any;
  public dep;
  // + 标识
  public __v_isRef = true;

  constructor(value: any) {
    this._value = isObject(value) ? reactive(value) : value;
    this.dep = new Set();
  }

  get value() {
    trackRefValue(this);
    return this._value;
  }

  set value(newVal: any) {
    if (hasChanged(newVal, this._value)) {
      this._value = newVal;
      triggerEffects(this.dep);
    }
  }
}

export function isRef(ref) {
  return !!ref?.__v_isRef;
}

单测也是通过。

13_01_isRef单测结果

二、实现unRef

unRef: 如果参数是一个ref则返回它的value,否则返回参数本身。

(一)单元测试

it('unRef', function () {
  const a = ref(1);

  expect(unRef(a)).toBe(1);
  expect(unRef(1)).toBe(1);
});

可以看到单测也比较简单,我们只需要根据是不是ref,然后返回.value还是数据本身即可,那就可以复用上面的isRef

(二)代码实现

// src/reactivity/ref.ts

export function unRef(ref) {
  return isRef(ref) ? ref.value : ref;
}
13_02_unRef单测结果

单测也全部通过了。😋

ps

🎯 如果您看到这里,请不要走开。
🎉 这是一个早起俱乐部:三更灯火五更鸡

⭐️ 寻找 志同道合 的小伙伴,我们一起 早起