vue模板解析实现
Vue 模板解析实现原理
Vue 的模板解析过程是将模板字符串转换为渲染函数(render function)的过程。核心流程分为模板编译、生成 AST、优化 AST 和生成渲染函数几个阶段。
模板编译阶段
Vue 通过编译器将模板字符串转换为抽象语法树(AST)。编译器首先对模板进行词法分析和语法分析,生成 AST 节点。例如:
<div id="app">{{ message }}</div>
会被解析为类似以下结构的 AST:
{
type: 1,
tag: 'div',
attrsList: [{ name: 'id', value: 'app' }],
children: [{
type: 2,
expression: '_s(message)',
text: '{{ message }}'
}]
}
生成 AST
解析器通过正则表达式匹配模板中的各种语法,如标签、属性、文本和插值表达式。对于每个匹配到的语法,解析器会创建对应的 AST 节点并建立父子关系。
文本解析示例:
const text = 'Hello {{ name }}'
const tokens = parseText(text)
// tokens: ['Hello ', { @binding: 'name' }]
优化 AST
优化阶段会对 AST 进行静态标记,标记静态节点和静态根节点。静态节点在后续更新中可以跳过比对,提升性能。
function markStatic(node) {
node.static = isStatic(node)
if (node.type === 1) {
for (let i = 0; i < node.children.length; i++) {
markStatic(node.children[i])
}
}
}
生成渲染函数
将优化后的 AST 转换为可执行的渲染函数代码。这个过程会递归遍历 AST,生成创建 VNode 的代码。
function generate(ast) {
const code = ast ? genElement(ast) : '_c("div")'
return new Function(`with(this){return ${code}}`)
}
生成的渲染函数类似:
function render() {
with(this) {
return _c('div', { attrs: { "id": "app" } }, [_v(_s(message))])
}
}
关键函数说明
_c: 创建元素 VNode_v: 创建文本 VNode_s: 转换为字符串
完整编译流程
- 将模板解析为 AST
- 对 AST 进行优化处理
- 将 AST 生成渲染函数字符串
- 通过 new Function 将字符串转换为可执行函数
自定义编译器
可以通过 Vue 的编译器选项自定义编译行为:
const { compile } = require('vue-template-compiler')
const { render } = compile('<div>{{ msg }}</div>')
console.log(render.toString())
运行时编译与预编译
Vue 提供了两种编译方式:

- 运行时编译:在浏览器中实时编译模板
- 预编译:通过 vue-loader 等工具提前编译模板
预编译是推荐的生产环境做法,可以减少运行时开销。






