在没有接触模板引擎之前,我们接受后台传来的json数据后需要将其拼接成字符串,然后将其插入到DOM中去,如果有一些复杂的业务逻辑,拼接代码会变得更加的繁琐,而且后期维护起来也十分的不方便。后来在项目中接触到一款十分强大的模板引擎,就是我们的doT,被它强大的功能深深的吸引住了。尤其在1.0.0版本后还新增了局部模板的功能,可扩展性非常的强大。刚开始看官方的文档时对局部模板这个功能还不是很懂,后来在网上搜寻了各种资料,才豁然开朗,分享一下自己的心得体会。
介绍
doT模板引擎是一个最快速最简洁的JavaScript模板引擎,在浏览器端和Nodejs端都适用。它小巧快速并且没有任何依赖,所有代码才一百多行,压缩后才4k,非常的轻量。

配置
在doT文件中有一个templateSettings属性用来配置doT的定界符(官方文档这么称呼,我们可以理解为模板的语法),我们也可以手动修改使用自己的定界符,但是建议使用默认的:
templateSettings: {
evaluate: /\{\{([\s\S]+?(\}?)+)\}\}/g,
interpolate: /\{\{=([\s\S]+?)\}\}/g,
encode: /\{\{!([\s\S]+?)\}\}/g,
use: /\{\{#([\s\S]+?)\}\}/g,
useParams: /(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g,
define: /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,
defineParams:/^\s*([\w$]+):([\s\S]+)/,
conditional: /\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,
iterate: /\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,
varname: "it",
// 控制空白字符,true - 全部去掉,false - 保留
strip: true,
// 性能优化设置,通过它调整性能,append 设置成 false,可能会产生更好的效果
append: true,
// 如果 'selfcontained' 为 true,doT 将毫无依赖的产生函数
selfcontained: false,
doNotSkipEncoded: false
},
在配置中有一个属性是varname,它的值是it,代表了在模板中传入对象所使用的变量名。
用法
首先介绍一下doT模板中常用的定界符代表的使用和含义:
{{= }} 用于插值(interpolation)
{{ }} 用于求值(evaluation)
{{? }} 条件语句
{{~ }} 数组迭代
{{! }} 用于编码求值
{{# }} 用于编译时求值/引入和局部模板
{{## #}} 用于编译时定义
赋值定界符
首先定义要赋值的模板,注意模板的type要写成text/x-dot-template。
在这里我们使用了的赋值定界符,用于在模板中进行赋值操作。这里使用的it就是我们在上面配置中定义好的varname变量。然后在JS中调用模板渲染到页面上去:
var person = {'name':'ace','age':20},
person1 = {'name':'john','age':21};
var doTemplate = doT.template($('#templ1').text());
$('body').html(doTemplate(person)+doTemplate(person1));
在这里我们获取到了模板函数doTemplate,然后将定义好的对象传入函数中,最后返回我们所需要的字符串插入到DOM中。这里我们对doTemplate函数进行了一次复用,定义了两个属性相同字面量传入。
求值定界符
如果传入到模板中的是一个对象,我们还可以通过求值定界符遍历输入对象中的属性:
在求值定界符中,我们可以写类似于js的语法。
var dataEval = {"name":"ace","age":20,"interests":"basketball","email":"ace@ly.com","phone":"110"};
var evalText = doT.template($("#templ2").text());
$('body').html(evalText(dataEval));
迭代定界符
有时候我们需要遍历对象中的数组,通过迭代定界符来遍历。但是要在但是需要在后面加上:value:index表示数组中的每个元素和索引值。
在这里我们传入的是一个对象,所以需要用~it.array来遍历我们的数组。
var dataArr = {"array":["banana","apple","orange"]};
var arrText = doT.template($("#templ3").text());
$('body').html(arrText(dataArr));
我们可以直接传入一个数组,遍历的时候就需要用~it直接来遍历数组值。
条件定界符
在模板中有时候我们需要对数据进行判断,进行不同的展示,这时我们就需要用到条件定界符。
条件模板前后都用单问号包裹,中间的双问号表示else。
var student = {'name':'ace','score':82}
var conditionText = doT.template($('#templ4').text());
$('body').html(conditionText(student))
对于条件判断,我们还可以使用求值定界符,对上面的进行如下改写:
模板定界符(doT新增功能)
在1.0.0之后的版本,doT加入的局部模板的功能,我们在模板中还可以定义一个局部模板。在主模板和子模板中我们都可以通过it变量引用到传入的对象。
首先通过两个#定义一个编译的需要引入局部模板的主模板def.father,在它里面定义了两个子模板def.child1和def.child2,然后通过一个#在编译时输入我们的主模板。如果没有这段输入代码,那么最后在编译时doT不会帮我们输出主模板的。
var dataPart = {
"name":"Corner",
"age":31,
"html":"html元素"
};
var defPart = {
"child1":"{{=it.name}} who?",
"child2":"{{=it.name}} how?"
};
var partText = doT.template($("#templ6").text(), undefined, defPart);
$("body").html(partText(dataPart));
在JS中我们首先定义需要传入的数据,然后定义一个子模板的对象。这个对象中包含了我们在模板中定义的两个子模板的名称和内容,在子模板内容中,我们还是通过it变量引用到传入的对象。然后在生成模板函数时我们将子模板的对象一起传给template。
赏