Vue3 ref的原理解析以及实践

前言

本篇作为Vue3中ref api的讲解,希望你拥有以下知识

实现ref

有这么一段代码,

  • 我们用一个副作用函数注入total的依赖
  • 再用一个副作用函数注入salePrice的依赖
let product = reactive({ price:5,quantity:2 })
let salePrice = 0
let total = 0

effect(()=>{
    total = product.price*product.quantity
})

effect(()=>{
    salePrice = product.price*1.1
})

此时我们不难发现销售总额应当为salePrice*product.quantity,于是我们定义销售总额,并注入依赖。

let saleTotal = 0
effect(()=>{
    saleTotal = salePrice*product.quantity
})

但此段代码不会像我们所想的那样运行,因为salePrice并不是一个响应式变量。此时如果你熟悉Vue3Api,你应该知道这里是一个使用ref的场景。

ref

ref函数接受一个值并返回一个响应式的、可变的Ref对象。Ref对象只有一个.value属性值。

第一种实现,通过reactive方法直接实现

function ref(intialValue){
    return reactive({value:intialValue})
}

虽然能行,但这并不是我们以及Vue3实现所真正实现的。

对象访问器

Vue3中ref使用了一个概念对象访问器,这属于JavaScript里计算属性的概念。下面我举例说明。

let user = {
    firstName:'jack',
    lastName:'chen',
    get name(){
        return `${this.firstName} ${this.lastName}`
    },
    set name(value){
        [this.firstName,this.lastName] = value.split(' ')
    }
}
console.log(user.name)//output:jack chen
user.name = 'jony j'
console.log(user)//output {
 firstName:'jony',
 lastName:'j',
}

如上代码中,我们并没有给user对象设置name的属性。而是通过set 和get 与name属性名间的逻辑关系,从而使得了name具有了计算属性。在我们改变name的同时也同时改变了与她相关的firstName以及lastName属性。这个概念同样也在ref api内使用

简易ref源代码

function ref(raw){
    const r = {
        get value(){
            track(r,'value')
            return raw
        }
        set value(newVal){
            raw = newVal
            trigger(r,'value')
        }
    }
	return r
}

以上代码中我们在ref函数内新建了一个对象,并运用了对象访问器,注入了与传入值相关的依赖,并在赋值时触发依赖从而达到了响应值。关于track和trigger函数的实现可参考reactive api内的实现。在Vue3中ref用于将一个普通类型的值转换为响应式,个人感觉类似于Vue2中计算属性的含义。

End

本篇参考了源代码讲解视频,对于ref的讲解不是完全全面。实现代码为简易版。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值