⚡ 30 秒速记
- 初始化状态,准备可执行的渲染逻辑
- 模板编译与运行时渲染是不同阶段
- 首次渲染读取状态并建立依赖
- 变化触发调度,再比较与更新宿主节点
- 编译优化减少运行时需要处理的范围
Vue 内部可以串成一条线:准备状态和渲染函数,第一次生成界面,数据变化后再刷新相关部分。 模板编译负责把声明变成可执行逻辑,响应式系统负责关联数据与更新,渲染器负责落实节点变化。静态内容可以在编译阶段被识别,减少后续工作。Vue 2 与 Vue 3 的内部角色和优化方法不同,但这三个职责仍能帮助定位问题发生在哪一层。
版本校准: 本文出现 Object.defineProperty、Dep、Watcher 和双端 Diff 时,主要描述 Vue 2 实现;Vue 3 使用 Proxy、effect 与新的渲染器路径。Vue 2 已于 2023-12-31 结束维护,新项目应以 Vue 3 为基线,旧项目参考 Vue 2 EOL 官方说明 制定迁移与安全策略。
# 一、Vue.js 运行机制全局概览
# 全局概览
这一节笔者将为大家介绍一下 Vue.js 内部的整个流程,希望能让大家对全局有一个整体的印象,然后我们再来逐个模块进行讲解。从来没有了解过 Vue.js 实现的同学可能会对一些内容感到疑惑,这是很正常的,这一节的目的主要是为了让大家对整个流程有一个大概的认识,算是一个概览预备的过程
首先我们来看一下笔者画的内部流程图。

大家第一次看到这个图一定是一头雾水的,没有关系,我们来逐个讲一下这些模块的作用以及调用关系。相信讲完之后大家对Vue.js内部运行机制会有一个大概的认识。
# 初始化及挂载

在
new Vue()之后。 Vue 会调用_init函数进行初始化,也就是这里的init过程,它会初始化生命周期、事件、 props、 methods、 data、 computed 与 watch 等。其中最重要的是通过Object.defineProperty设置setter与getter函数,用来实现「响应式」以及「依赖收集」,后面会详细讲到,这里只要有一个印象即可。
初始化之后调用
$mount会挂载组件,如果是运行时编译,即不存在 render function 但是存在 template 的情况,需要进行「编译」步骤。
# 编译
compile编译可以分成 parse、optimize 与 generate 三个阶段,最终需要得到 render function。

1. parse
parse 会用正则等方式解析 template 模板中的指令、class、style等数据,形成AST。
2. optimize
optimize的主要作用是标记 static 静态节点,这是 Vue 在编译过程中的一处优化,后面当update更新界面时,会有一个patch的过程, diff 算法会直接跳过静态节点,从而减少了比较的过程,优化了patch的性能。