思考功能
- isRef用来判断对象是否为ref对象
- unRef帮助提取ref对象的值
根据单侧实现功能
ref.spec.ts
/** 看得见的思考
* 1. 给ref实例一个固定标识
* 2. 如果能取到该标识证明就是ref对象
*/
it("isRef", () => {
const a = ref(1);
const user = reactive({
age: 1,
});
expect(isRef(a)).toBe(true);
expect(isRef(1)).toBe(false);
expect(isRef(user)).toBe(false);
});
/** 看得见的思考
* 1. 可以利用isRef判断
* 2. 如果是ref对象,则返回ref.value,否则直接返回原值
*/
it("unRef", () => {
const a = ref(1);
expect(unRef(a)).toBe(1);
expect(unRef(1)).toBe(1);
});
实现 isRef
/*
* @Author: Lin zefan
* @Date: 2022-03-17 18:23:36
* @LastEditTime: 2022-03-20 15:11:23
* @LastEditors: Lin zefan
* @Description: ref
* @FilePath: \mini-vue3\src\reactivity\ref.ts
*
*/
import { reactive } from ".";
import { isObject, hasChanged } from "../shared";
import { isTracking, trackEffect, triggerEffect } from "./effect";
class RefImpl {
_dep: any;
private _value: any;
+ // ref对象标识
+ __v_isRef = true;
constructor(value) {
/**
* 1. 需要判断value是基本类型还是引用类型
* 2. 引用类型需要用reactive包裹,做到深度侦听
*/
this._value = convert(value);
this._dep = new Set();
}
get value() {
/** 思考
* 1. get要收集依赖
*/
isTracking() && trackEffect(this._dep);
return this._value;
}
set value(newVal) {
/** 思考
* 1. 先判断新老值,值不相等再做更新
* 2. 更新ref.value
* 3. 更新依赖的值
*/
if (hasChanged(this._value, newVal)) return;
this._value = convert(newVal);
triggerEffect(this._dep);
}
}
function convert(value) {
return isObject(value) ? reactive(value) : value;
}
export function ref(ref) {
return new RefImpl(ref);
}
+ export function isRef(ref) {
+ return !!ref.__v_isRef;
+ }
实现 unRef
/*
* @Author: Lin zefan
* @Date: 2022-03-17 18:23:36
* @LastEditTime: 2022-03-21 23:28:20
* @LastEditors: Lin zefan
* @Description: ref
* @FilePath: \mini-vue3\src\reactivity\ref.ts
*
*/
export function unRef(ref) {
return isRef(ref) ? ref.value : ref;
}