vue是如何避免重复渲染的?

2,187 阅读2分钟

vue双向绑定原理,每个watcher对象都绑定了唯一的id,当组件props和data对象属性发生变化时,将会触发watcher对象update方法。

image.png

lazy属性是避免computed属性里用到(props和data)对象属性变化导致的重复调用update

默认情况下watcher对象的sync是false,会调用queueWatcher方法

image.png 这个方法里主要判断了当前工作队列中是否已经有这个watcher对象,

如果工作队列中没有此而且队列也还没开始执行,加到队列中去。

如果工作队列中没有watcher对象,但是队列已经开始执行,如果插入位置小于等于当前正在执行的warcher位置,则插入当前的执行warcher的后面。如果插入位置大于当前正在执行的warcher位置,则比较执行位置index后面watcher的id 和 传入watcher的id

nextTick是异步执行方法,vue对此进行了封装,针对不同浏览器对js原生异步的函数的支持,简单点理解就是一个setTimeout方法

因为是异步执行方法,所以在主线程的方法执行完,才执行任务队列中flushSchedulerQueue,

下面我们来看一个列子:

image.png

测试下来name属性变化了三次,但是只触发了一次更新。我们来分析一下原因:

name属性第一次改变时,queue中插入  name属性里Dep对象下的所有watcher对象,因主线程函数并没执行完,此时flushSchedulerQueue方法还在等待

name属性第二次改变时,queue中并没有插入name属性里Dep对象下的所有watcher对象,此时flushSchedulerQueue方法还在等待

name属性第三次改变时,queue中还是没有插入name属性里Dep对象下的所有watcher对象,此时主线程函数执行完毕,回调任务队列中flushSchedulerQueue方法,更新视图