ref和reactive
# 区别
reactive
API 对传入的target
类型有限制,必须是对象或者数组类型,而对于一些基础类型(比如 String、Number、Boolean)是不支持的。但是有时候从需求上来说,可能我只希望把一个字符串变成响应式,却不得不封装成一个对象,这样使用上多少有一些不方便
我们需要一个基本类型作为响应式,如果用
reactive
的话就需要reactive({value:xxx})
这样传进去所以
vue3
就提供了ref
这种写法,让你不需要手动包装成对象。所以这也是为什么ref
包装的响应式对象需要.value
才能拿到值的原因。ref
本质上还是reactive
# Vue3的响应式原理
- Vue.js 3.0 在响应式的实现思路和 Vue.js 2.x 差别并不大,主要就是 劫持数据的方式改成用 Proxy 实现 , 以及收集的依赖由 watcher 实例变成了组件副作用渲染函数 。
- 由于 Proxy 劫持的是整个对象,所以我们可以检测到任何对对象的修改,弥补了 Object.defineProperty API 的不足。
- Object.defineProperty 是在初始化阶段,即定义劫持对象的时候就已经递归执行了,而 Proxy 是在对象属性被访问的时候才递归执行下一步 reactive,这其实是一种延时定义子对象响应式的实现,在性能上会有较大的提升
- 依赖收集:劫持
get
函数,通过Reflect.get
求值,然后会执行 track 函数收集依赖副作用函数,把当前激活的副作用函数activeEffect
作为依赖,然后收集到target
相关的depsMap
对应key
下的依赖集合dep
中 - 通知依赖更新:劫持
set
函数,主要就做两件事情, 首先通过 Reflect.set 求值 , 然后通过 trigger 函数派发通知 ,并依据 key 是否存在于 target 上来确定通知类型,即新增还是修改;trigger 函数主要做了四件事情: - 通过 targetMap 拿到 target 对应的依赖集合 depsMap;
- 创建运行的 effects 集合;
- 根据 key 从 depsMap 中找到对应的 effects 添加到 effects 集合;
- 遍历 effects 执行相关的副作用函数。
所以每次 trigger 函数就是根据 target 和 key ,从 targetMap 中找到相关的所有副作用函数遍历执行一遍。
最近更新时间: 2022/09/28 16:26:36
- 01
- 2023/07/03 00:00:00
- 02
- 2023/04/22 00:00:00
- 03
- 2023/02/16 00:00:00