《Vuejs设计与实现》6.1 引入ref的概念

135 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第25天,点击查看活动详情

Proxy只能代理非原始值类型,但是其实日常中我们使用原始值的时候更多.

比如在vue2中,我相信这段代码大家都写过,这里show就是一个布尔型。

export default{
 data(){
     return {
       show:false
     }
 }
}

如果你非要使用reactive,你就得再包一层对象,const state = reative({show:false}),这种写法其实在vue3中并不推荐,vue2是由于设计上,导致我们只能再包一层对象,vue3则希望通过composition API的新写法去改变这一点.

为了解决这个问题,vue3推出了ref api,ref就是为了代理原始值类型的变量,例如Number,Boolean,String这些。

我们可以简单的写一下,一个函数,传入原始值,返回一个响应式的变量。

image.png

同时,我们使用Object.defineProperty去定义一个标志,用来表示这个变量是一个ref.之所以用这个方法定义变量,因为这样定义可以指定不可枚举,不可修改的。

这样我们就完成了一个基本的ref方法。得益于我们之前封装过的reactive,我们还可以实现readOnlyRefshallowRef. 但其实这样属于一种比较投机取巧的办法,我认为vue3源码中应该不是这样实现的,等看看后面的章节,作者会怎么去介绍ref.

也正是因为ref内部这个wrapper,我们在使用的时候,必须xx.value才能赋值,引起了许多诟病,尤老板也新增加了RFC,新增了几个实验性的API;例如$ref$$ref这些。

谈到ref,我就得说一下unref,这两个API应该算我在vue3里使用最多的了,unref的实现也特别简单,一句话的事情。 function unref(maybeRef){ return maybeRef.value ? maybeRef.value : maybeRef.} 在日常使用的时候,如果只需要读取值,我们可以直接使用unref,等需要修改值了再使用xxx.value