当前位置: 首页 > article >正文

《Vue进阶教程》第三十一课:ref的初步实现

 往期内容:

《Vue进阶教程》第二十课:lazy懒执行

《Vue进阶教程》第二十一课:支持缓存

《Vue进阶教程》第二十二课:自定义更新(调度器)

《Vue进阶教程》第二十三课:渲染计算属性的结果

《Vue进阶教程》第二十四课:优化

《Vue进阶教程》第二十五课:watch基本概念

《Vue进阶教程》第二十六课:实现侦听函数

《Vue进阶教程》第二十七课:实现侦听对象

《Vue进阶教程》第二十八课:实现新旧值

《Vue进阶教程》第二十九课:立即执行的回调

《Vue进阶教程》第三十课:watchEffect

1 为什么需要ref

由于proxy只能代理引用类型数据(如: 对象, 数组, Set, Map...), 需要一种方式代理普通类型数据(String, Number, Boolean...)

设计ref主要是为了处理普通类型数据, 使普通类型数据也具有响应式

除此之外, 通过reactive代理的对象可能会出现响应丢失的情况. 使用ref可以在一定程度上解决响应丢失问题

2 初步实现

1) 包裹对象

既然proxy不能代理普通类型数据, 我们可以在普通类型数据的外层包裹一个对象

proxy代理包裹的对象(wrapper). 为了统一, 给包裹对象定义value属性, 最后返回wrapper的代理对象

function ref(value) {
  const wrapper = {
    value: value,
  }

  return reactive(wrapper)
}

测试用例

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="./reactive.js"></script>
  </head>
  <body>
    <script>
      function ref(value) {
        const wrapper = {
          value: value,
        }

        return reactive(wrapper)
      }

      // count是一个proxy对象
      const count = ref(1)
      effect(() => {
        // 访问proxy对象的属性 触发 getter 收集依赖
        console.log(count.value)
      })

      setTimeout(() => {
        count.value = 2
      }, 1000)
    </script>
  </body>
</html>

2) 添加标识

按照上面的实现, 我们就无法区分一个代理对象是由ref创建, 还是由reactive创建, 比如下面的代码

ref(1)
reactive({value: 1})

为了后续能够对ref创建的代理对象自动脱ref处理, 即不用.value访问.

考虑给ref创建的代理对象添加一个标识

示例

function ref(value) {
  const wrapper = {
    value: value,
  }

  // 给wrapper添加一个不可枚举, 不可写的属性__v_isRef
  Object.defineProperty(wrapper, '__v_isRef', {
    value: true,
  })

  return reactive(wrapper)
}

在Vue3源码中, 虽然不是按上述方式实现的, 但是可以这样去理解


http://www.kler.cn/a/460858.html

相关文章:

  • 创龙3588——debian根文件系统制作
  • Ubuntu Server安装谷歌浏览器
  • 【微软,模型规模】模型参数规模泄露:理解大型语言模型的参数量级
  • 苹果解锁工具iToolab UnlockGo 中文安装版(附教程+补丁) 2024年6月ios17.4.1可用(记得点赞)解压密码请看文章!!! 评论区获取最新链接
  • Mac 版本向日葵退出登录账号
  • 数据结构(ing)
  • 2025元旦源码免费送
  • 探索数据之美,Plotly引领可视化新风尚
  • 代码随想录算法训练营DAY17
  • Rust日志库tklog0.2.9—支持混合时间文件大小备份模式
  • windows下VS release调试
  • Stm32小实验1
  • 【GIS教程】高程点制作DEM并使用ArcgisPro发布高程服务Elevation Layer
  • win32汇编环境下,双击窗口程序内生成的listview列表控件的某行,并提取其内容的示例程序
  • Nmap实用语法简介
  • 使用WebRTC进行视频通信
  • 基于SC-FDE单载波频域均衡MQAM通信链路matlab仿真,包括帧同步,定时同步,载波同步,MMSE信道估计等
  • 在windows上使用vscode和cmake编译c++ 过程记录
  • git 中 工作目录 和 暂存区 的区别理解
  • 网络安全的8个热门趋势和4个渐冷趋势
  • 2 、什么是Java中的不可变类
  • 三层交换机和三层网络结构 有什么区别和联系
  • JavaWeb Servlet的getInitParameter、业务层、控制反转IOC和依赖注入DI
  • 水上救命稻草,充气救生板的关键救援效能|深圳鼎跃
  • 滴滴数据分析80道面试题及参考答案
  • 苹果系统MacOS下ObjectC建立的App程序访问opencv加载图片程序