Vue进阶系列 参考至 VueDemo
Vue 运行机制全局概览
内部流程图:
一、初始化和挂载
1- 初始化
new Vue()
之后会调用 init
初始化函数。它会初始化生命周期、时间、methods、data、computed、watch等。
- Vue的数据响应。
是通过Object.defineProperty
设置 getter
和 setter
函数,来实现【响应式】和【依赖收集】。
2- 挂载
初始化后调用$mount
会挂载组件,随后经过编译,通过render function
。如果是运行时编译,那么就不需要render function
。
但是如果时存在template
的情况, 就是需要进行【编译】
步骤了。
二、编译
编译分为三个阶段,parse
optimize
generate
.最终需要得到 render function
。
- parse 【解析器】
parse
会用正则等方式解析 template 模板中的指令、class、style等数据,形成AST。
- optimize 【优化器】
optimize
的主要作用是标记 static 静态节点,这是 Vue 在编译过程中的一处优化,后面当 update
更新界面时,会有一个 patch
的过程, diff
算法会直接跳过静态节点,从而减少了比较的过程,优化了 patch 的性能。
- generate 【代码生成器】
generate
是将AST
转换为render function
字符串的过程。得到结果的是render function
的字符串,以及 staticRenderFns
字符串。
经过编译的三个阶段后,组件中就会出现渲染VNode 的 render function
三、响应式
这里的 getter
跟 setter
已经在之前介绍过了,在 init
的时候通过 Object.defineProperty
进行了绑定,它使得当被设置的对象被读取的时候会执行 getter
函数,而在当被赋值的时候会执行 setter
函数。
当渲染的时候,需要所需的值,因此会通过getter来进行【依赖搜集】。
将数据的观察者对象 Watcher
对象存放在Dep
中,这样当数据发生变化的时候,就会出发setter
. setter 通知之前的【依赖搜集】得到的Dep中的watcher
对象,如果需要重新渲染试图,watcher 就会调用update
来更新DOM。当然中间还有patch
过程。
四、Virtual DOM 虚拟DOM
我们知道render function
会转换成虚拟DOM节点。Virtual DOM 其实是一颗以javascript对象作为基础的树。
实际上就是对真实DOM树的一个抽象表示。最终虚拟DOM会通过一系列的操作得到真实的DOM。
由于 Virtual DOM 是以 JavaScript 对象为基础而不依赖真实平台环境,所以使它具有了跨平台的能力,比如说浏览器平台、Weex、Node 等。
{
tag: 'div',
children: [
{
tag: 'a',
text: 'love me'
}
]
}
// 渲染为
<div>
<a>love me</a>
</div>
实际上节点有许许多多的属性,比如isStatic
代表是否为静态节点。 isComment
代表是否注释节点。
五、更新渲染
会通过 setter -> Watcher -> update
的流程来修改对应的视图,那么最终是如何更新视图的呢?
当数据变化后,执行 render function
就可以得到一个新的 VNode
节点,我们如果想要得到新的视图,最简单粗暴的方法就是直接解析这个新的 VNode
节点,然后用 innerHTML
直接全部渲染到真实 DOM 中。但是其实我们只对其中的一小块内容进行了修改,这样做似乎有些「浪费」。
这就要说到patch
了。我们会将新的 VNode
与旧的 VNode
一起传入 patch
进行比较,经过 diff
算法得出它们的「差异
」。最后我们只需要将这些「差异
」的对应 DOM 进行修改即可。
再看全局
接下来我们继续深入学习吧,加油~~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。