通过模板字符串生成正式模板。
模板字符串:
var template = `
<ul>
<% for(var i = 0; i < data.supplies.length; i++) { %>
<li><%= data.supplies[i] %></li>
<% } %>
</ul>
`;
该模板使用 <%...%> 防止 JavaScript 代码,使用 <%=...%> 输出 JavaScipt 表达式。
编译过程:
function compile(template) {
var evalExpr = /<%=(.+?)%>/g;
// 这个是从'<%='开始到'%>'结束,如果中间换行了不会匹配,例如 <%=val%>那么val就是被匹配到的值
// 正则表达式里边<.+?>表示匹配:'<' 开始,其后至少含有1个除了 '>' 的任意字符,且再遇到 '>',就结束匹配。
var expr = /<%([\s\S]+?)%>/g;
// 这个是从'<%'开始到'%>'结束,换行了也会继续匹配到
// [\s\S] 表示全部字符,包括空白字符和非空白字符
template = template
.replace(evalExpr, '`); \n echo( $1 ); \n echo(`') // 1
.replace(expr, '`); \n $1 \n echo(`'); // 2
template = 'echo(`' + template + '`);'; // 3
var script =
`(function parse(data) {
var output = "";
function echo(html) {
output += html;
}
${ template }
return output;
})`;
return script;
}
var div = document.getElementById("test");
var parse = eval(compile(template));
// innerHTML 只能针对一个元素进行添加内容
div.innerHTML = parse({ supplies: [ "broom", "mop", "cleaner"] });
template 在编译过程中有 3 个转变状态,下面是每一个状态 template 的代码:
// 1 : .replace(evalExpr, '`); \n echo( $1 ); \n echo(`')
"
<ul>
<% for(var i = 0; i < data.supplies.length; i++) { %>
<li>`);
echo( data.supplies[i] );
echo(`</li>
<% } %>
</ul>
"
// 2 : .replace(expr, '`); \n $1 \n echo(`');
"
<ul>
`);
for(var i = 0; i < data.supplies.length; i++) {
echo(`
<li>`);
echo( data.supplies[i] );
echo(`</li>
`);
}
echo(`
</ul>
"
// 3 : 'echo(`' + template + '`);'
"echo(`
<ul>
`);
for(var i = 0; i < data.supplies.length; i++) {
echo(`
<li>`);
echo( data.supplies[i] );
echo(`</li>
`);
}
echo(`
</ul>
`);"
参考链接:https://segmentfault.com/q/1010000013871493
参考书籍:《ES6标准入门》