vue compile源码实现
Vue 编译源码实现分析
Vue 的模板编译过程是将模板字符串转换为渲染函数的过程,主要分为解析、优化和生成三个阶段。
解析阶段
将模板字符串转换为抽象语法树(AST),通过正则表达式匹配模板中的标签、属性、文本等内容,生成对应的 AST 节点。
// 示例代码:解析模板生成 AST
const ast = parse(template, options)
AST 节点通常包含以下信息:
- 标签类型(元素、文本、插值表达式等)
- 标签名
- 属性列表
- 子节点列表
优化阶段
对 AST 进行静态标记,标记静态节点和静态根节点,用于后续的渲染优化。
// 示例代码:优化 AST
optimize(ast, options)
优化过程主要包括:
- 标记静态节点(不会变化的节点)
- 标记静态根节点(子节点全是静态的节点)
- 提升静态节点,避免重复渲染
生成阶段
将优化后的 AST 转换为可执行的渲染函数代码字符串。
// 示例代码:生成渲染函数代码
const code = generate(ast, options)
生成的代码通常是类似这样的字符串:
with(this){return _c('div',{attrs:{"id":"app"}},[_v("Hello "+_s(name))])}
核心模块解析
解析器(Parser)
解析器负责将模板字符串转换为 AST,主要通过正则表达式和状态机实现。
function parse(template, options) {
// 解析逻辑
// 返回 AST
}
解析过程包括:
- 解析开始标签和属性
- 解析文本内容
- 解析结束标签
- 处理指令和插值表达式
优化器(Optimizer)
优化器遍历 AST,标记静态节点。
function optimize(root, options) {
if (!root) return
markStatic(root)
markStaticRoots(root, false)
}
标记方法:
- 静态节点:节点不包含动态绑定,子节点也都是静态的
- 静态根节点:节点本身是静态的,且有子节点
代码生成器(Code Generator)
代码生成器将 AST 转换为渲染函数代码。
function generate(ast, options) {
const code = ast ? genElement(ast, options) : '_c("div")'
return {
render: `with(this){return ${code}}`,
staticRenderFns: state.staticRenderFns
}
}
生成过程:
- 处理元素节点,生成
_c()调用 - 处理文本节点,生成
_v()调用 - 处理表达式,生成
_s()调用
运行时辅助函数
生成的渲染代码会使用以下辅助函数:
_c():创建 VNode(createElement)_v():创建文本 VNode_s():转换为字符串(toString)_l():渲染列表(renderList)_e():创建空 VNode(createEmptyVNode)
编译结果示例
对于模板:
<div id="app">{{ message }}</div>
编译后的渲染函数:
with(this){
return _c('div',
{attrs:{"id":"app"}},
[_v(_s(message))]
)
}
编译配置选项
Vue 编译器支持多种配置选项:
modules:自定义模块directives:自定义指令isPreTag:判断是否是 pre 标签isUnaryTag:判断是否是单标签mustUseProp:必须使用 prop 绑定的属性
性能优化策略
Vue 的编译优化主要包括:

- 静态节点提升,避免重复渲染
- 静态属性提升,减少比对开销
- 事件处理函数缓存,避免重复创建
这些优化使得 Vue 在运行时能够更高效地执行差异比对和更新。






