一、变化侦测篇
1、vue是数据驱动的,数据驱动视图简单来说就是数据变化引起视图变化,那么第一步就是先要知道数据什么时候发生变化,也就是说对数据的变化要进行侦测。侦测分为两类:Object的变化侦测和Array的变化侦测
二、虚拟DOM篇
1、虚拟DOM
:vue中较重要的一个概念是虚拟DOM
,所谓虚拟DOM,就是用一个JS
对象来描述一个DOM
节点
<div class="a" id="b">我是内容</div>
{
tag:'div', // 元素标签
attrs:{ // 属性
class:'a',
id:'b'
},
text:'我是内容', // 文本内容
children:[] // 子元素
}
2、VNode类
:Vue
中存在一个VNode
类,通过这个类,我们就可以实例化出不同类型的虚拟DOM
节点
3、patch
:总之一句话:以新的VNode
为基准,改造旧的oldVNode
使之成为跟新的VNode一样,这就是patch过程要干的事。
整个patch
无非就是干三件事(创建、删除、更新都涉及真是DOM操作
):
- 创建节点:新的
VNode
中有而旧的oldVNode
中没有,就在旧的oldVNode
中创建。 - 删除节点:新的
VNode
中没有而旧的oldVNode
中有,就从旧的oldVNode
中删除。 - 更新节点:新的
VNode
和旧的oldVNode
中都有,就以新的VNode
为准,更新旧的oldVNode
。
三、模版编译篇
1、整体渲染流程:就是把用户写的类似于原生HTML
的模板经过一系列处理最终反应到视图中称之为整个渲染流程
因为有了模版编译,才有了虚拟DOM(VNode),才有了后续的视图更新
2、模版编译中的一个优化:编译时有一步是标记静态节点,挡在patch的过程中,DOM-Diff算法会直接跳过静态节点,从而减少了比较的过程,优化了patch的性能。
3、模板编译内部具体流程图,便于理解。流程图如下: 内部具体分为三个阶段:
(1)模版解析阶段:
主要做的工作是把用户在标签内写的模版使用正则等方式解析成抽象语法树(AST),顾名思义就是把用户所写的模版根据一定的解析规则解析出有效的信息,最后用这些信息形成AST。而这一阶段在源码中对饮解析器(parser)模块,可能用到的解析器有:HTML解析器、文本解析器、过滤器解析器
文本信息和标签属性信息却又是存在于HTML标签之内的,所以在解析整个模板的时候它的流程应该是这样子的:HTML解析器是主线,先用HTML解析器进行解析整个模板,在解析过程中如果碰到文本内容,那就调用文本解析器来解析文本,如果碰到文本中包含过滤器那就调用过滤器解析器来解析。
(2)优化阶段
为什么要有优化阶段:是为了提高虚拟DOM
中patch
过程的性能。在优化阶段将所有静态节点都打上标记,这样在patch
过程中就可以跳过对比这些节点。
<ul>
<li>我是文本信息</li>
<li>我是文本信息</li>
<li>我是文本信息</li>
<li>我是文本信息</li>
<li>我是文本信息</li>
</ul>
// li是静态节点,ui是静态根节点
优化阶段其实就干了两件事:
- 在
AST
中找出所有静态节点并打上标记; - 在
AST
中找出所有静态根节点并打上标记;
(3)代码生成阶段
所谓代码生成阶段,到底是要生成什么代码?答:要生成render
函数字符串。
简单的来说就是Vue
只要调用了render
函数,就可以把模板转换成对应的虚拟DOM
所谓代码生成其实就是根据模板对应的抽象语法树AST
生成一个函数,通过调用这个函数(render函数)就可以得到模板对应的虚拟DOM
render函数怎么来的:
(1)用户手写的(可以在Vue
组件选项中手写一个render
)
(2)vue自己生成的(Vue
就要自己根据模板内容生成一个render
函数)