Vue 响应式原理
2023-12-09
Vue
响应式就是能够自动跟踪数据变化,进而更新页面。要跟踪数据,在 js 里,可以拦截对象的读写,有两种方式:getter/setter 和 proxy,vue2采用前者,vue3 用的 proxy。
其过程是:
- 代理数据
- 依赖收集
- 触发更新
其中,代理数据,vue2 用到 Object.defineProperty,vue3 用到 Proxy。
代理数据
Object.defineProperty
设置对象的 getter
和 setter
来监听对象的操作。getter
里收集依赖,setter
就是观察者,数据发生更新时,通知订阅者更新视图。
受限于 defineProperty
,getter/setter
无法追踪属性的新增和删除。对数组的话,监听下标会造成性能浪费,因而vue2中重写了数组方法,重写之后,有些数组属性拦截不掉,比如直接修改长度,或以下标来赋值。
Proxy
Proxy 针对整个对象,因此,无需遍历所有属性,只需代理一层,即可监听同级所有属性的变化。对于深层对象,还是要递归
依赖收集
两个类,订阅者 Dep
,观察者 Watcher
,Dep 收集依赖项,也就是一系列 Watcher,以便知道数据更新了该更新哪里的视图
Watcher 需要知道自己属于哪里,是 data、computed、watch。
拿 Vue2 来说。Vue初始化后,data 会转换成 getter/setter 形式,来追踪数据。当渲染函数执行的时候,会触发一次getter,此时收集依赖项,也就是一个个 Watcher。之后更改数据,会触发 setter,通知收集到的相关 Watcher 更新页面