isRef & unRef这两个工具函数实现起来很简单,几行代码就可以搞定
isRef
unRef
结语
isRef
测试
期望值这里其实应该字如其名可以看出来
it('isRef', () => {
const a = 1
const b = ref(a)
const user = reactive({
age: 1
})
expect(isRef(a)).toBe(false)
expect(isRef(b)).toBe(true)
expect(isRef(user)).toBe(false)
})
实现
我们只需要在之前的基础之上定义一个变量用来判断就行了,这里我用的是枚举,你们变量也是可以的,不是ref肯定就没有new RefImpl,那么自然这个值就为undefined,我们返回时如果是undefined会与期望值不一致,这里和之前的isReactive的返回可以做同样的双重取反操作
export enum RefFlags {
IS_REF = '__v_isRef'
}
class RefImpl {
private _value: any
public dep
private _rawValue: any
public [RefFlags.IS_REF] = true
constructor(value: any) {
this._rawValue = value
// value 为对象时转为reactive包一层
this._value = convert(value)
this.dep = new Set()
}
get value() {
trackRefValue(this)
return this._value
}
set value(newValue) {
if (hasChanged(this._rawValue, newValue)) return
this._rawValue = newValue
this._value = convert(newValue)
triggerEffects(this.dep)
}
}
export function isRef(ref) {
return !!ref.__v_isRef
}
unRef
测试
it('unRef', () => {
const a = 1
const b = ref(a)
expect(unRef(a)).toBe(1)
expect(unRef(b)).toBe(1)
})
实现
这里利用isRef就可以很轻松的写出来
export function isRef(ref) {
return !!ref.__v_isRef
}
export function unRef(ref) {
return isRef(ref) ? ref.value : ref
}
结语
写代码其实也可以看出来先后顺序,做吃出合理规划,之后写代码会变得无比轻松