1._.template 支持以下三种模板:
<% %> - to execute some code (执行一些代码)
<%= %> - to print some value in template (在模板中打印或者说成输出一些值)
- <%- %> - to print some values HTML escaped (打印一些HTML转义的值)
解释:
<% %> 里包裹的是一些可执行的 JavaScript 语句,比如 if-else 语句,for 循环语句,等等。
<%= %> 会打印传入数据相应的 key 的值,
<%- %> 和前者相比,多了步 HTML 实体编码的过程,可以有效防止 XSS 攻击。
例:
<div></div>
<script src="underscore.js"></script>
<script type="text/template" id="tpl">
<ul class="list">
<% _.each(obj, function(e, i, a){ %>
<% if (i === 0) %>
<li><%- e.name %> // 这里会进行实体编码
<% else if (i === a.length - 1) %>
<li class="last-item"><%= e.name %></li>
<% else %>
<li><%= e.name %></li>
<% }) %>
</ul>
</script>
<script>
// mock data
var data = [{name: "<script>"}, {name: "orange"}, {name: "peach"}];
var compiled = _.template(document.getElementById("tpl").innerHTML);
var html = compiled(data);
// console.log(html)
document.querySelector("div").innerHTML = html;
</script>
2.自定义template 模板
如果你不喜欢它默认的模板风格,也可以自己定义,但是需要注意的是 key 必须和源码中的 key 保持一致,才能覆盖。
自定义模板规则有两种方式,一种是直接修改 _.templateSettings 变量(不推荐,修改了源码中的变量)
//源码中的templateSettings
_.templateSettings = {
// 三种渲染模板
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
自定义成 {{ }} 的形式
_.templateSettings = {
interpolate: /\{\{(.+?)\}\}/g
};
var template = _.template("Hello {{ name }}!");
var ans = template({name: "Mustache"});
console.log(ans); // Hello Mustache!
推荐方法:
var settings = {
interpolate: /\{\{(.+?)\}\}/g // 会覆盖_.templateSettings.interpolate
};
var template = _.template("Hello {{ name }}!", settings);//通过settings传入规则
var ans = template({name: "Mustache"});
console.log(ans); // Hello Mustache!
3.预编译
模板引擎一般都带有预编译功能,_.template 也不例外。
什么是预编译?有什么用?
上面的代码有两个痛点:
性能:模板引擎渲染的时候依赖 Function 构造器实现,Function 与 eval、setTimeout、setInterval 一样,提供了使用文本访问 javascript 解析引擎的方法,但这样执行 javascript 的性能非常低下。
调试:由于是动态执行字符串,若遇到错误调试器无法捕获错误源,导致模板 BUG 调试变得异常痛苦。在没有进行容错的引擎中,局部模板若因为数据异常甚至可以导致整个应用崩溃,随着模板的数目增加,维护成本将剧增。
如果我们 JavaScript 代码中直接保存 .template 的结果,那么以上两个问题就不复存在。而 .template(tplText).sourceData 则保存了 _.template(tplText) 返回的方法字符串。
另外:template()模板语法中的一些语法:
1.if else
//错误
<%if(!item.iLike){ %>
<div class="iLike"></div>
<% }%>
<% else {%>
<div class="iLike active"></div>
<% } %>
//正确写法
<%if(!item.iLike){ %>
<div class="iLike"></div>
<% } else {%>
<div class="iLike active"></div>
<% } %>