# 运行机制概述
# 初始化及挂载
- 在 new Vue() 之后。 Vue 会调用 _init 函数进行初始化
- 初始化生命周期、事件、 props、 methods、 data、 computed 与 watch 等
- 通过 Object.defineProperty 设置 setter 与 getter 函数,用来实现
响应式
以及依赖收集
- 初始化之后调用 $mount 挂载组件
- 如果是运行时编译,即不存在 render function
- 存在 template 的情况,需要进行
编译
步骤。
# 编译
compile编译分为 parse
# parse
使用正则表达式等方式解析
Template模板中的指令,class,style等等数据,形成AST
# optimize
optimize 的主要作用是标记 static 静态节点 update
更新界面时,会有一个 patch
的过程, diff
算法会直接跳过静态节点,从而减少了比较的过程,优化了 patch
的性能
# generate
generate 是将 AST
转化成 render function
字符串的过程,得到结果是 render 的字符串以及 staticRenderFns
在经历过 parse
,optimize
,generate
这三个阶段以后,组件中就会存在渲染 VNode render function
了
# 响应式
getter
跟 setter
在 init 的时候通过 Object.defineProperty 进行了绑定
- 当被设置的对象被读取的时候会执行
getter
函数 - 当被赋值的时候会执行
setter
函数
当 render function
被渲染的时候,因为会读取所需对象的值,所以会触发 getter
函数进行依赖收集,目的是将观察者 Watcher
对象存放到当前闭包中的订阅者 Dep
的 subs
中
修改对象的值的时候,会触发对应的 setter
, setter
通知之前依赖收集得到的 Dep
中的每一个 Watcher
,告知他们我的值改变了,需要重新渲染视图。这时候这些 Watcher
就会开始调用 update
来更新视图,当然这中间还有一个 patch
的过程以及使用队列来异步更新的策略
# Virtual DOM
render function
会被转化成 VNode
节点
Virtual DOM
是一棵以 JavaScript 对象( VNode 节点)作为基础的树,用对象属性来描述节点,实际上它只是一层对真实 DOM 的抽象- 最终可以通过一系列操作使这棵树映射到真实环境上
- Virtual DOM 是以 JavaScript 对象为基础而不依赖真实平台环境,所以它具有了跨平台的能力
- 浏览器平台
- Weex
- Node
- ...
简单示例
{
tag: 'div',
children: [
{
tag: 'a',
text: 'click me'
}
]
}
2
3
4
5
6
7
8
9
渲染为
<div>
<a>click me</a>
</div>
2
3
# 更新视图
在修改一个对象值的时候,会通过 setter
-> Watcher
-> update
的流程来修改对应的视图
当数据变化后,执行 render function
就可以得到一个新的 VNode
节点,将新 VNode
与旧 VNode
一起传入 patch
进行比较,经过 diff 算法得出它们的差异
,只需要将这些差异
的对应 DOM 进行修改即可。