运行机制概述

初始化及挂载
- 在 new Vue() 之后。 Vue 会调用 _init 函数进行初始化
- 初始化生命周期、事件、 props、 methods、 data、 computed 与 watch 等
- 通过 Object.defineProperty 设置 setter 与 getter 函数,用来实现
响应式以及依赖收集 - 初始化之后调用 $mount 挂载组件
- 如果是运行时编译,即不存在 render function
- 存在 template 的情况,需要进行
编译步骤。
编译
compile编译分为 ,
,三个阶段,最终需要得到parse
使用正则表达式等方式解析Template模板中的指令,class,style等等数据,形成
optimize
optimize 的主要作用是,当 update 更新界面时,会有一个 patch 的过程, diff 算法会直接跳过静态节点,从而减少了比较的过程,优化了 patch 的性能
generate
generate 是将 AST 转化成 render function 字符串的过程,得到结果是 render 的字符串以及 字符串。
在经历过 parse,optimize,generate这三个阶段以后,组件中就会存在渲染 所需的 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'
}
]
}渲染为
<div>
<a>click me</a>
</div>更新视图
在修改一个对象值的时候,会通过 setter -> Watcher -> update 的流程来修改对应的视图
当数据变化后,执行 render function 就可以得到一个新的 VNode 节点,将新 VNode 与旧 VNode 一起传入 patch 进行比较,经过 diff 算法得出它们的差异 ,只需要将这些差异的对应 DOM 进行修改即可。

