Vue的模板渲染过程主要分为三个核心阶段:模板解析 → 生成渲染函数 → 虚拟DOM渲染。
1. 模板解析(Parse)
目标:将模板字符串(如
<div>{{ msg }}</div>)转化为 抽象语法树(AST)。过程:
使用正则表达式和词法/语法分析器解析模板。
识别标签、属性、指令(如
v-if)、插值表达式({{}})等。构建树形结构的AST对象,描述模板的层级关系和语义。
关键点:AST是模板的结构化表示,为后续优化和代码生成做准备。
2. 生成渲染函数(Generate)
目标:将AST转化为 渲染函数(
render函数)。过程:
遍历AST,生成可执行的JavaScript代码字符串。
处理静态内容(如纯文本)进行 静态提升(Static Hoisting),避免重复渲染。
处理动态内容(如插值、指令)生成响应式依赖收集逻辑。
最终返回一个函数:
function render() { return createElement('div', msg) }。
关键点:
渲染函数返回 虚拟DOM(VNode),而非真实DOM。
在Vue 2中,通过
compileToFunctions完成;Vue 3中通过@vue/compiler-core实现。
3. 虚拟DOM渲染(Render & Patch)
目标:将VNode转化为真实DOM,并处理更新。
过程:
首次渲染:
执行
render()函数生成VNode。通过
patch方法将VNode挂载到真实DOM(mount)。
数据更新:
触发响应式系统(如
setter)。重新执行
render()生成新VNode。通过
diff算法对比新旧VNode,计算最小更新范围。用
patch更新真实DOM(仅修改变化部分)。
关键点:
虚拟DOM:用JS对象模拟DOM结构,提升跨平台能力。
Diff算法:通过同层比较、key复用等策略优化更新性能。
面试加分点
性能优化:
静态提升:静态节点在渲染函数外生成,避免重复创建。
Patch Flags(Vue 3):标记动态内容类型,跳过静态节点对比。
Block Tree(Vue 3):优化
v-for等场景的diff效率。
编译时优化:
Vue 3将编译时优化前置(如预编译静态节点),减少运行时开销。
响应式联动:
模板中的动态属性(如
{{ msg }})会被转化为响应式依赖,数据变化时触发重新渲染。
关键方法:
vm.$mount():触发挂载流程。vm._update():执行patch更新DOM。
总结回答
Vue的模板渲染分三步:
解析模板为AST,识别结构和指令;
生成渲染函数,将AST转化为返回VNode的JS函数;
执行渲染函数得到VNode,通过
patch和diff算法高效更新真实DOM。
核心优势是通过虚拟DOM和编译优化(如静态提升)提升性能,响应式系统驱动数据变化时的精准更新。