🎯 一、为什么要掌握模板引擎?
掌握模板引擎的实现,意味着你理解了:
- 字符串解析 + 正则处理
- JS 动态执行函数的能力(Function 构造器)
- 模板编译原理(Vue/React 的编译阶段核心)
- 面试官会以此判断你是否掌握数据 → 视图的底层过程
🧠 二、我们要实现的目标
输入模板:
const template = `
<h1>{{ title }}</h1>
<ul>
{{ for item in list }}
<li>{{ item }}</li>
{{ end }}
</ul>
`;
输入数据:
const data = {
title: '水果列表',
list: ['🍎 苹果', '🍌 香蕉', '🍇 葡萄']
};
输出 HTML:
<h1>水果列表</h1>
<ul>
<li>🍎 苹果</li>
<li>🍌 香蕉</li>
<li>🍇 葡萄</li>
</ul>
🧩 三、核心思想
将模板字符串编译为 JS 执行函数:
function render(data) {
return new Function('data', `with(data){ return `${compiledTemplate}`; }`)(data);
}
✍️ 四、实现步骤:简易模板引擎核心代码
function compile(template) {
// 1. 替换 {{ xxx }} → ${xxx}
let code = template
.replace(/{{\s*(.*?)\s*}}/g, (_, expr) => `${${expr}}`);
// 2. 处理 for 循环
code = code
.replace(/${for (.+?) in (.+?)}/g, '`; for(let $1 of $2) { output += `')
.replace(/${end}/g, '`;} output += `');
// 3. 生成函数体
const finalCode = `
let output = ``;
with(data) {
output += `${code}`;
}
return output;
`;
return new Function('data', finalCode);
}
✅ 使用方式:
const render = compile(template);
const result = render(data);
console.log(result);
📌 五、支持语法
| 语法 | 示例 | 功能 |
|---|---|---|
| 插值 | {{ title }} | 数据替换 |
| for 循环 | {{ for item in list }}...{{ end }} | 遍历数组 |
✅ 六、测试输出结果
<h1>水果列表</h1>
<ul>
<li>🍎 苹果</li>
<li>🍌 香蕉</li>
<li>🍇 葡萄</li>
</ul>
完美符合预期 ✅
🎯 七、进阶点(可拓展)
| 进阶功能 | 实现建议 |
|---|---|
| if 判断 | 支持 {{ if condition }}...{{ else }}...{{ end }},同理替换为 JS |
| 函数调用 | 在 with(data) 作用域中可直接调用 |
| AST 编译 | 高级模板引擎(如 Vue)基于 AST,非必需但可了解 |
❗ 八、面试易错点
| 问题 | 解法 |
|---|---|
| 模板变量取不到值 | 使用 with(data) 注入作用域 |
| 标签嵌套错乱 | 必须正确关闭循环、判断等逻辑块 |
| 安全问题 | 最终执行的是 JS 代码,谨防 XSS 注入(不适合生产环境) |