前端Vue 源码分析-逻辑层

Vue 源码分析-逻辑层

预期的效果:

先摘一段源码,作为简单的分析

前端Vue 源码分析-逻辑层

 

预期的效果:

监听input的输入,input在输入的时候,会触发 watch与computed函数,并且会更新原始的input的数值。所以直接跟input相关的处理就有3处,但实际上会有连带性的触发,触发watch的input函数的时候,还会触发this.answer对应的依赖处理

看看内部是如何处理的:

Vue在初始化data的时候,会通过Object.defineProperty重新定义input的set与get访问接口,同时会创建一个记录并且保持其数据对应的依赖watcher对象的Dep对象,这个Dep对象是通过闭包的方式保存在每个独立的data中,而Dep就是用于收集当前data所依赖的Watcher对象

简单来说

在data中定义了input,那么意味着需要对这个变量进行defineProperty的处理,并创建Dep对象

watch中的input函数会变成一个Watcher对象,因为它与input有关系,所以需要在data的input的Dep中保存一份引用

computed中的compiledMarkdown函数会变成一个Watcher对象,,因为它与input有关系,所以需要在data的input的Dep中保存一份引用

input数据的监控内部创建的Dep的结构就是如下:

 

前端Vue 源码分析-逻辑层

 

根据当前这个例子的代码,watch与computed明明只有2个对应的Watcher对象,为什么subs会有3个呢?多增加的一个是干什么的?这个多出的Watcher就是vue2中的虚拟dom的处理,后面会提到

 

这里最终可以简单的梳理下更新的流程:当input数据发生变化的时候,只需要调用响应依赖的Watcher对象,Watcher对象就会负责各自的更新处理。这里面向对象的设计优势就体现出来了,将行为分布在各个对象中,并让这些对象负责自己的行为,所以每个不同Watcher对象更新各自的特点,处理各自的逻辑

更新

更新逻辑:

vue1的 dom更新方式采用队列+直接更新的处理,这种简单粗暴。vue2在vue1的设计上,继续保留了队列的处理方式,同时结合了时下最流行的 virtual dom

记得在Vue1中,每个Watcher对象都会保存各自的dom节点的处理方式,通过对Watcher的的处理达到直接更新DOM的目的。Vue2因为引入的Virtual Dom的机制,所以Watcher的工作就需要变化了,大多数的Watcher不再直接负责DOM的更新操作,而只是更新数据。这里用了大多数,因为还有一个Watcher是跟Virtual Dom相关的。所以这就是在上文提到的Dep中会多一个Watcher的原因了

Virtual DOM

虚拟DOM的文章现在已经很多了,但是如何紧密结合vue中,到实际的运用是我们分析的重点,这里只是粗略下,我还要抽时间把算法看完先

原理:

简单的说,直接通过JS操作浏览器API去绘制DOM节点是很慢的,大量的页面处理中,开发者不经意就会调用更多多余或者重复的操作,这种是有性能开销的。那么有什么办法减少这种是误操作呢?就是通过一种方式能算出来最小的更新量,从而提高效率。既然要计算出对小的更新量,那么就会有对比,需要通过对新旧两个节点的对比从而计算出。DOM的操作很慢,但是JS确很快的,DOM 树上的结构、属性信息我们都可以很容易地用 JavaScript 对象表示出来,既然我们可以用JS对象表示DOM结构,那么当数据状态发生变化而需要改变DOM结构时,我们先通过JS对象表示的虚拟DOM计算出实际DOM需要做的最小变动,反过来,就可以根据这个用 JavaScript 对象表示的树结构来构建一棵真正的DOM树,操作实际DOM更新了, 从而避免了粗放式的DOM操作带来的性能问题。

根据上面的原理,Virtual DOM在实现上首先就必须先建立可以对比的JS对象,这个叫做vnode,也就是虚拟DOM了,这个对象是真实DOM结构的一个映射,通过对比更新前后vnode的变化差异diff,记录下来的不同就是我们需要对页面真正的 DOM 操作。

Virtual DOM算法,简单总结下包括几个步骤:

用JS对象描述出DOM树的结构,然后在初始化构建中,用这个描述树去构建真正的DOM,并实际展现到页面中

当有数据状态变更时,重新构建一个新的JS的DOM树,通过新旧对比DOM数的变化diff,并记录两棵树差异

把步骤2中对应的差异通过步骤1重新构建真正的DOM,并重新渲染到页面中,这样整个虚拟DOM的操作就完成了,视图也就更新了

看到这里可以简单总结下,Vue中Watcher与Virtual DOM的关系:

Watcher 是来决定你要不要更新这个dom

虚拟DOM是用来找出怎么以最小的代价来更新

Vue2中对应的逻辑

这里不会涉及算法,并非这章的重点,主要看下整个更新过程中,虚拟DOM逻辑是怎么配合工作的。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspspj.html