我们都知道,在ES5中字符串拼接方法比较繁琐。同一条字符串不能换行且要频繁用+拼接字符串。以拼接几个
for(var i = 0 ; i < 100 ; i ++){
html += '- '
+'hello'
+'world'
+'' + Math.random() +''
+'
可以看出字符串拼接频繁用’'和+,导致代码可读性较差
for(var i = 0 ; i < 100 ; i ++){
html += `
hello
world
${ Math.random() }
`
}
ES6取消了如此麻烦的字符串拼接方法,统一用反引号(``)包裹字符串,中间插入变量时统一用${要插入的变量}。极大的简化了代码,增强可读性。
介绍了ES6新增的字符串拼接方法,我们用这个方法实现一下简单的字符串模板渲染。在实际页面开发中,不可能拼接一次字符串就拼接一次字符串。而是会有一个模板,只需要按照模板写好字符串就可以直接实现字符串的拼接插入;
1. 因为模板里面肯定包含js,所以我们对js代码进行特殊标记; <% js代码都放在这里 %>
2. html结构在我们眼里就是字符串; html没有任何包裹;
3. 输出的变量, 对变量进行一个特殊标记; <%= 变量都放在这里 %>
代码如下:
<script type="text/html" id="template">
<ul>
<% for(var i = 0 ; i < 10 ; i ++){ %>
<li> <strong> <%= i %></strong> <i> <%= i + 1 %> </i>
<button>这是个按钮</button></li>
<% } %>
</ul>
</script>
这里注意这个包含模板字符串的script标签type类型为text/html。表明这是一个html结构。
模板写好了,那么我们便需要处理一下这个模板字符串。我们的目标是将它处理成一个符合规范的js代码。
处理目标:
print( ``
);
for(var i = 0 ; i < 10 ; i ++){
print(`` );
print(i);
print(``)
}
print( `` );
注:print()是我们自定义的用来处理字符串函数,这里以拼接字符串的功能举例
1.将开头结尾的特殊标识处理掉
正则和字符串处理API——replace
template_str = template_str.replace(/<%[^=](.*?)%>/g ,`\`); \n $1 \n print(\`` );
处理结果:
<ul>` );
for(var i = 0 ; i < 10 ; i ++){
print( `<li>`) <%= i %> print( `</li>`)
}
print( `</ul>
2.将处理后的字符串处理为目标字符串
处理代码:
template_str = template_str.replace(/<%=(.*?)%>/g ,`\`); \n print($1) \n print(\`` );
处理结果:
<ul>` );
for(var i = 0 ; i < 10 ; i ++){
print( `<li> `) print(i) print( `</li>`)
}
print( `</ul>
3.继续处理模板
处理代码:
template_str = `print(\`${ template_str }\`)`;
处理结果:
print( ``
);
for(var i = 0 ; i < 10 ; i ++){
print( ` ` ) print(i) print( ``)
}
print( `` );
4.将处理后的字符串加入函数体内,为了方便字符串加入,函数也用字符串写
var fn_str = `(function( data ){
var html = "";
function print(str){
html += str
}
${template_str} // 这是刚才解析好的模板;
return html;
})`;
5.将这个含有函数的字符串处理为一个真正的函数:
eval:将json格式的字符串处理为js代码
字符串内function需要加括号,需要加括号防止eval转换成匿名函数后报错
var temp_fn = eval( fn_str );
此时temp_fn便是处理好的函数。
完整的处理字符串的代码如下:
function renderTemplate( template_str , data ){
//date为增强函数功能,可以传入参数。这个例子中可以不需要
template_str = template_str.replace(/<%[^=](.*?)%>/g ,`\`); \n $1 \n print(\`` );
template_str = template_str.replace(/<%=(.*?)%>/g ,`\`); \n print($1) \n print(\`` );
//最后一步处理;
template_str = `print(\`${ template_str }\`)`;
var fn_str = `(function( data ){
var html = "";
function print(str){
html += str
}
${template_str} // 这是刚才解析好的模板;
return html;
})`;
// 把这个字符串变成一个真正的函数;
var temp_fn = eval( fn_str );
var res = temp_fn( data );
return res;
}
// 获取模板字符串
var template_str = document.getElementById("template").innerHTML
// 调用函数处理字符串
var html = renderTemplate( template_str )
// 将字符串插入list内
document.getElementById("list").innerHTML = html;