简单实现vue中compile
实现 Vue 的 compile 功能
Vue 的 compile 功能是将模板字符串编译成渲染函数的过程。以下是简化实现的核心步骤:
解析模板字符串
使用正则表达式或字符串操作将模板字符串解析为抽象语法树(AST)。例如,解析 {{}} 插值和指令:
function parse(template) {
const ast = {
type: 'root',
children: []
};
let text;
while (template) {
if (template.startsWith('{{')) {
const endIndex = template.indexOf('}}');
if (endIndex !== -1) {
text = template.substring(2, endIndex);
ast.children.push({
type: 'interpolation',
content: text.trim()
});
template = template.substring(endIndex + 2);
}
} else {
const tagStart = template.indexOf('<');
if (tagStart === 0) {
const tagEnd = template.indexOf('>');
const tag = template.substring(1, tagEnd);
ast.children.push({
type: 'element',
tag
});
template = template.substring(tagEnd + 1);
} else {
text = template.substring(0, tagStart !== -1 ? tagStart : template.length);
ast.children.push({
type: 'text',
content: text
});
template = template.substring(text.length);
}
}
}
return ast;
}
转换 AST 为渲染函数
将 AST 转换为可执行的渲染函数代码字符串:
function generate(ast) {
const code = `with(this){return ${processNode(ast)}}`;
return new Function(code);
}
function processNode(node) {
switch (node.type) {
case 'root':
return `[${node.children.map(processNode).join(',')}]`;
case 'element':
return `_c('${node.tag}')`;
case 'text':
return `_v('${node.content}')`;
case 'interpolation':
return `_s(${node.content})`;
default:
return '';
}
}
实现渲染辅助函数
提供 _c(创建元素)、_v(创建文本节点)、_s(字符串化)等辅助函数:
function renderHelper() {
return {
_c(tag) {
return document.createElement(tag);
},
_v(text) {
return document.createTextNode(text);
},
_s(val) {
return val == null ? '' : String(val);
}
};
}
整合编译流程
将解析、生成和渲染辅助函数整合为一个 compile 函数:
function compile(template) {
const ast = parse(template);
const render = generate(ast);
return Object.assign(render, renderHelper());
}
// 使用示例
const render = compile('<div>{{message}}</div>');
const vm = { message: 'Hello Vue!' };
const el = render.call(vm);
document.body.appendChild(el);
处理动态数据绑定
通过 Proxy 或 Object.defineProperty 实现数据响应式,在数据变化时重新渲染:
function observe(data) {
return new Proxy(data, {
set(target, key, value) {
target[key] = value;
renderDOM();
return true;
}
});
}
let currentRender;
function renderDOM() {
document.body.innerHTML = '';
document.body.appendChild(currentRender.call(vm));
}
const vm = observe({ message: 'Hello Vue!' });
currentRender = compile('<div>{{message}}</div>');
renderDOM();
// 测试数据变化
setTimeout(() => {
vm.message = 'Data changed!';
}, 1000);
以上实现展示了 Vue 模板编译的核心原理,实际 Vue 的实现会更复杂,包括更多指令处理、虚拟 DOM 优化等。







