手撸vue3核心源码——响应式原理(isRef和unRef)

今天来实现一下ref的功能函数,isRef与unRef

isRef

isRef和isReactive一样,都是用于检测数据类型,isRef是检测是不是一个ref对象,跟isReactive函数实现起来一样,我们先来写一个单元测试

这里要实现的功能是,检测ref对象肯定就通过返回true,检测普通类型数据以及reactive对象都是false

 it("it should return a boolean", () => {
        let obj = ref(1)
        let a = 1
        let b = reactive({ user: 1 })

        expect(isRef(obj)).toBe(true)
        expect(isRef(a)).toBe(false)
        expect(isRef(b)).toBe(false)
    })

  我们在ref.ts中把逻辑写好,首先肯定要返回一个isRef的函数对象,接着我们读取某个属性,如果是ref,那么可以读到,如果不是ref那么它没有这个属性,就会为false

class RefImpl {
    private _value
    private _raw
    public dep
    //是否是ref的标识
    public __v_isRef = true
    constructor(value) {
        //保存没有代理前的value
        this._raw = value
        //做对象类型检测
        this._value = isObject(value) ? reactive(value) : value
        this.dep = new Set()
    }
    get value() {
        trackRefValue(this.dep)
        return this._value

    }
    set value(newValue) {
        if (!isHasChanged(this._raw, newValue)) return
        this._raw = newValue
        this._value = newValue
        tiggerEffect(this.dep)

    }
}

我们用一个__v_isRef来标识ref,当我们能读到这个属性是那么肯定就是ref对象了


export function isRef(value) {
    return !!value.__v_isRef
}

为什么要用!!转义呢,因为当我们传入的数据比如是1 a {name: 1}这种不是响应式对象 以及reactive对象,他们身上就没有__v_isRef属性,返回值是undefined,因此用!!转义一下,变成布尔值


unRef

在 Vue 3 中,unRef用于获取一个可能是响应式对象或 ref 对象的原始值,以避免对响应式对象的重复包装或 ref 对象的.value访问, 如果不是一个ref对象的话也返回它的值,先来看一下单测

it("it should return a value", () => {
        let obj = ref(2)
        let a = 1

        expect(unRef(obj)).toBe(2)
        expect(unRef(a)).toBe(1)
    })

我们想一下思路。当我们传入的是ref对象时,我们返回.value即可,若不是ref对象那好办,直接返回它的值

我们来实现一下, 我们只用检测一下是不是ref即可,上面的isRef刚好可以检验

export function unRef(ref) {
    return isRef(ref) ? ref.value : ref
}

这样代码就已经都实现啦,是不是很容易了,我们在写源码的过程中一定要理清楚逻辑关系


写在最后

最近博客已经往掘金迁移了,希望大家也能多多支持在掘金的博客创作,与君共勉!

掘金主页

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值