vue2响应式原理

文章类型:Vue

发布者:admin

发布时间:2023-05-21

一:是什么

组件中的data发生变化,立即触发视图的更新

二:图解

1:首先data中的数据会进行遍历添加getter和setter方法,也叫做数据劫持

2:当render中使用到data中的数据时,则调用getter方法,同时会记录下这个调用线,

3:watcher作为一个观察者,就观测着依赖线,也叫依赖收集

4:当data进行数据更新时,则Notify派发更新,通知watcher,watch就看记录的依赖线

5:watcher就通知所有用到的数据render进行重新渲染,就会出现新旧虚拟Dom,diff算法,找到需要更新的位置,更新为真实dom

三:原理

1:使用数据劫持+观察者模式(发布订阅模式)

2:数据劫持,通过Object.defineProperty对对象的每一个属性添加get/set,(读取触发get,修改触发set)

3:依赖收集,每个组件实例都会对应一个watcher实例,会在组件渲染过程中把使用到的数据进行记录,为依赖,之后当触发setter时,进行通知watcher派发更新,watcher通知组件进行重新渲染

四:主要步骤

1:Observer:将普通对象转换为响应式对象,(通过object.defineProperty)

主要是通过递归遍历对象的每个属性,包括子属性,在他们上面绑定getter和setter,

当对象被读取或者赋值修改,使得内部的 变化能够被感知到,能够被监听到

2:Dep:依赖的意思,就是发布者,为对象的每个属性创建Dep实例,每个实例都会记录依赖和通知依赖更新,

主要是记录依赖和派发更新,读取时进行依赖收集,修改时进行派发更新

3:Watcher:订阅者,是Observer和Dep通讯桥梁,当数据改变,通知依赖对应的watcher实例去执行重新渲染

4:Scheduler:dep通知watcher之后,不可能一通知就更新,这样会导致性能低下。

通过nextTick方法,开启一个队列,缓存把需要执行的watcher放到微队列里面

如果同一个watcher多次触发,只会推入到队列一次,避免了重复数据和不必要的Dom操作

根据环境决定采用Promise.then、MutationObserver 和 setImmediate

五:object.defineProperty

1:特点

通过下标方式修改数组或者给对象新增属性,不能触发重新渲染, 因为不能拦截到这些操作,靠重写函数解决

2:缺点

深度监听需要一次性递归到底,计算量大

描述符只有get和set,无法监听新增和删除属性

无法监听原生数组

直接修改数组的长度

3:解决方案

通过重写数组的方法,push、pop、shift、unshift、splice、sort、reverse

通过内置set、$set等api实现



评论
0条评论遵守法律,文明用语,共同建设文明评论区

暂无评论,快来发表第一条评论吧~