vue compile 实现
Vue 编译实现原理
Vue 的编译过程是将模板字符串转换为渲染函数的过程,主要包括模板解析、优化和代码生成三个阶段。
模板解析阶段
模板解析阶段将模板字符串转换为抽象语法树(AST)。Vue 使用正则表达式和有限状态机技术解析模板,识别模板中的标签、属性、指令和文本节点。
// 简化的解析逻辑示例
function parse(template) {
const stack = [];
let root;
let currentParent;
while(template) {
// 解析标签开始
if (template.startsWith('<')) {
const tagMatch = template.match(/^<([a-z][^\s>]*)/);
if (tagMatch) {
const node = {
type: 1,
tag: tagMatch[1],
attrsList: [],
children: []
};
// 处理属性
// ...
if (!root) root = node;
if (currentParent) currentParent.children.push(node);
stack.push(node);
currentParent = node;
template = template.slice(tagMatch[0].length);
}
}
// 解析文本
else {
const textEnd = template.indexOf('<');
const text = textEnd > 0 ? template.slice(0, textEnd) : template;
if (text) {
currentParent.children.push({
type: 3,
text: text.trim()
});
}
template = textEnd > 0 ? template.slice(textEnd) : '';
}
}
return root;
}
优化阶段
优化阶段对 AST 进行静态分析,标记静态节点和静态根节点。静态节点在后续更新时可以跳过比对,提升性能。
function optimize(root) {
markStatic(root);
markStaticRoots(root);
}
function markStatic(node) {
node.static = isStatic(node);
if (node.type === 1) {
for (let i = 0; i < node.children.length; i++) {
const child = node.children[i];
markStatic(child);
if (!child.static) {
node.static = false;
}
}
}
}
function isStatic(node) {
// 判断节点是否为静态
// 没有动态绑定、指令等
return true;
}
代码生成阶段
代码生成阶段将优化后的 AST 转换为可执行的渲染函数代码字符串。这个字符串通过 new Function 转换为真正的渲染函数。
function generate(ast) {
const code = ast ? genElement(ast) : '_c("div")';
return new Function(`with(this){return ${code}}`);
}
function genElement(el) {
if (el.staticRoot && !el.staticProcessed) {
return genStatic(el);
}
const data = genData(el);
const children = genChildren(el);
return `_c('${el.tag}'${data ? `,${data}` : ''}${children ? `,${children}` : ''})`;
}
编译结果示例
对于一个简单模板 <div id="app">{{message}}</div>,编译后生成的渲染函数类似:
function render() {
with(this) {
return _c('div', {attrs: {"id": "app"}}, [_v(_s(message))])
}
}
其中 _c 是创建元素的函数,_v 是创建文本节点的函数,_s 是转换为字符串的函数。
运行时编译与预编译
Vue 提供两种编译方式:运行时编译和预编译。运行时编译在浏览器中完成,需要包含完整的编译器代码。预编译通过 vue-loader 等工具在构建时完成,生产环境更推荐预编译方式以减小体积。
编译器优化技术
现代 Vue 编译器采用多项优化技术,如静态提升、补丁标志、树形结构优化等,进一步提升了渲染性能。这些优化在 Vue 3 中尤为显著,使得虚拟 DOM 比对更加高效。







