实现简版模板引擎
手写一个字符串模板引擎
模板引擎(这里特指用于 Web 开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的 HTML 文档。
- ES6 模板字符串 $
表达式 转换
实现
js
// {{ xxx }}表达式 转换
export function compileTpl(template, data) {
// const reg = /{{([a-zA-Z_$][a-zA-Z0-9_.]*)}}/g
const reg = /{{\s*?([a-zA-Z_$][a-zA-Z0-9_.]*)\s*?}}/g
// 多一个括号,replace 回调中第二个参数 key 就起作用了
return template.replace(reg, (row, key, offset, string) => {
// return data[key] || raw;
var paths = key.split('.')
// var lookup = data[key];
while (paths.length > 0) {
lookup = lookup[paths.shift()]
}
// 匹配中了则读取替换,否则替换为空字符串 (原始匹配 row)
// return lookup || row;
return lookup || ''
})
}
// testing
const tpl = `<p>My name is {{ name}}, I'm {{age}} age, my friend is {{friend.name}}</p>`
const data = {
name: 'siri',
age: 4,
friend: {
name: 'alice'
}
}
console.log(compileTpl(tpl, data))
// 使用 exec
function render(template, data) {
const reg = /\{\{(\w+)\}\}/ // 模板字符串正则
if (reg.test(template)) {
// 判断模板里是否有模板字符串
const name = reg.exec(template)[1] // 查找当前模板里第一个模板字符串的字段
template = template.replace(reg, data[name]) // 将第一个模板字符串渲染
return render(template, data) // 递归的渲染并返回渲染后的结构
}
return template // 如果模板没有模板字符串直接返回
}
js
// ES6 模板字符串 ${xxx}
// 1
function compileTpl(tpl, data) {
return tpl(data)
}
const tpl = (data) =>
`<p>My name is ${data.name}, I'm ${data.age} age, my friend is ${data.friend.name}</p>`
const data = {
name: 'siri',
age: 4,
friend: {
name: 'alice'
}
}
console.log(compileTpl(tpl, data))
测试用例
知识点
replace()
参考: