数据监听
Vue 3 中数据监听的实现
众所周知,
Object.defineProperty 由于每次只能监听对象一个键的get 、set,导致需要循环监听,浪费性能,而vue3 的Proxy 可以一次性监听到所有属性Object.defineProperty 无法监听数组,必须通过增强并替换原型链方法的方式处理数组监听,而Proxy 则可以直接监听数组变化- 由于
Object.defineProperty 只能监听对象,导致vue2 的data 属性必须通过一个返回对象的函数方式初始化,而vue3 则更加多元化,可以监听任意数据
在日常开发中,

reactive 依托于Proxy 语法,分别在访问器特性中的get 中触发track ,set 中触发trigger 实现数据获取时的依赖收集和数据变化时的触发更新ref 则依托于RefImpl 实现类中维护value 属性的getter 和setter ,使实例在使用value 属性时分别触发track 和trigger 方法,实现依赖收集和触发更新computed 方法依托于ComputedImpl 实现类,完成对getter 函数中的数据进行依赖收集,最后通过构造器中effect 属性,构建一个包含调度器的副作用函数来实现数据更新
reactive.ts
export interface Target {
[ReactiveFlags.SKIP]?: boolean // 是否无效标识,用于跳过监听
[ReactiveFlags.IS_REACTIVE]?: boolean // 是否已被reactive相关api处理过
[ReactiveFlags.IS_READONLY]?: boolean // 是否被readonly相关api处理过
[ReactiveFlags.RAW]?: any // 当前代理对象的源对象,即target
}
以及四个基于
export const reactiveMap = new WeakMap<Target, any>()
export const shallowReactiveMap = new WeakMap<Target, any>()
export const readonlyMap = new WeakMap<Target, any>()
export const shallowReadonlyMap = new WeakMap<Target, any>()
Links
- https://mp.weixin.qq.com/s/lI3r-pTP1f-Fh3S4RSG_vA
Vue3 源码解析 — 数据监听篇