ref的实现原理-详细步骤

330 阅读2分钟

如果参数是一个基本类型,ref会把一个基本类型包装成一个对象类型,也支持传数组或者对象,最后也会变成proxy

官方用法

image.png

我们现在来实现它

  • 创建ref.ts文件,导出ref方法
  • 创建一个RefImpl类

image.png

RefImpl实现

image.png

  • 我们要把原始值变成响应式
  • toReactive中判断是不是对象,如果是对象就去用reactive去用proxy代理一下
  • 如果设置值与原始值不一样,我们就进行处理,但是新设置的值也有可能是对象,所以我们还是要经过toReactive处理一下,然后把新值再作为原始值存放

我们依然要进行依赖收集

image.png

加一个标识

image.png

实现toRefs

image.png

image.png

  • 参数是一个对象,也有可能是数组
  • 先判断是数组还是对象
  • 如果是数组,创建一个新数组
  • 遍历参数,每一项用toRef处理,结果收集起来,返回出去
  • toRef里将对象和属性用ObjectRefImpl处理,当取值的时候从原对象里取,设置同样如此,这个类就做了层代理
  • 本质就是被代理的过程中,访问了一次,访问的属性就进行了依赖收集

测试

image.png

也可以直接用toRef

image.png

  • 这样我们就可以直接结构写了,不经过toRefs或者toRef,就会丧失响应式

  • 我们在使用数据的时候,都是把响应式的数据toRefs,在模板里用到的时候不需要用.value来获取,原理就是调用了proxyRefs,来把一个响应式的值变为普通值

proxyRefs的实现

image.png

  • 参数是一个对象
  • 用proxy代理一下,get的时候看看取到的值上有没有_v_isRef标识,也就是看看它是不是一个ref,如果是,则取它的value值,不是就直接返回
  • set的时候同样去判断是不是ref值,如果是设置它的value,不是就直接设置
  • 就是一个反向取值的过程,这样做的原因就是便于模板取值