在没有接触模板引擎之前,我们接受后台传来的json数据后需要将其拼接成字符串,然后将其插入到DOM中去,如果有一些复杂的业务逻辑,拼接代码会变得更加的繁琐,而且后期维护起来也十分的不方便。后来在项目中接触到一款十分强大的模板引擎,就是我们的doT,被它强大的功能深深的吸引住了。尤其在1.0.0版本后还新增了局部模板的功能,可扩展性非常的强大。刚开始看官方的文档时对局部模板这个功能还不是很懂,后来在网上搜寻了各种资料,才豁然开朗,分享一下自己的心得体会。
介绍 doT模板引擎是一个最快速最简洁的JavaScript模板引擎,在浏览器端和Nodejs端都适用。它小巧快速并且没有任何依赖,所有代码才一百多行,压缩后才4k,非常的轻量。
配置 在doT文件中有一个templateSettings属性用来配置doT的定界符(官方文档这么称呼,我们可以理解为模板的语法),我们也可以手动修改使用自己的定界符,但是建议使用默认的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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" , strip : true , append : true , selfcontained : false , doNotSkipEncoded : false },
在配置中有一个属性是varname
,它的值是it
,代表了在模板中传入对象所使用的变量名。
用法 首先介绍一下doT模板中常用的定界符代表的使用和含义:
{{= }} 用于插值(interpolation) {{ }} 用于求值(evaluation) {{? }} 条件语句 {{~ }} 数组迭代 用于编码求值 {{# }} 用于编译时求值/引入和局部模板 {{## #}} 用于编译时定义
赋值定界符 首先定义要赋值的模板,注意模板的type要写成text/x-dot-template。
<script id="templ1" type="text/x-dot-template"> <div>Hi {{=it.name}}!</div> <div>Your age is {{=it.age || ''}}</div> </script>
谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里
在这里我们使用了的赋值定界符,用于在模板中进行赋值操作。这里使用的it就是我们在上面配置中定义好的varname变量。然后在JS中调用模板渲染到页面上去:
var person = {'name' :'ace' ,'age' :20 }, person1 = {'name' :'john' ,'age' :21 };var doTemplate = doT.template ($('#templ1' ).html ()); $('body' ).html (doTemplate (person)+doTemplate (person1));
在这里我们获取到了模板函数doTemplate,然后将定义好的对象传入函数中,最后返回我们所需要的字符串插入到DOM中。这里我们对doTemplate函数进行了一次复用,定义了两个属性相同字面量传入。
求值定界符 如果传入到模板中的是一个对象,我们还可以通过求值定界符遍历输入对象中的属性:
<script id="templ2" type="text/x-dot-template"> {{ for(var prop in it) { }} <div>key:{{= prop }} --- value:{{= it[prop] }}</div> {{ } }} </script>
在求值定界符中,我们可以写类似于js的语法。
var dataEval = {"name" :"ace" ,"age" :20 ,"interests" :"basketball" ,"email" :"ace@ly.com" ,"phone" :"110" };var evalText = doT.template ($("#templ2" ).html ()); $('body' ).html (evalText(dataEval));
谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里
迭代定界符 有时候我们需要遍历对象中的数组,通过迭代定界符来遍历。但是要在但是需要在后面加上:value:index
表示数组中的每个元素和索引值。
<script id="templ3" type="text/x-dot-template"> {{~it.array:value:index}} <div>index:{{= index+1 }}--value:{{= value }}!</div> {{~}} </script>
在这里我们传入的是一个对象,所以需要用~it.array
来遍历我们的数组。
var dataArr = {"array" :["banana" ,"apple" ,"orange" ]};var arrText = doT.template ($("#templ3" ).html ()); $('body' ).html (arrText (dataArr));
我们可以直接传入一个数组,遍历的时候就需要用~it
直接来遍历数组值。
条件定界符 在模板中有时候我们需要对数据进行判断,进行不同的展示,这时我们就需要用到条件定界符。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <script id="templ4" type="text/x-dot-template"> <div>姓名:{{=it.name}}</div> <div>成绩:{{=it.score}}</div> {{? it.score<60}} <div>等级:不及格</div> {{?? it.score<70}} <div>等级:及格</div> {{?? it.score<80}} <div>等级:良好</div> {{?? it.score<90}} <div>等级:优秀</div> {{?? it.score<100}} <div>等级:棒极了</div> {{??}} <div>等级:数据有误</div> {{?}} </script>
条件模板前后都用单问号包裹,中间的双问号表示else。
var student = {'name' :'ace' ,'score' :82 }var conditionText = doT.template ($('#templ4' ).html ()); $('body' ).html (conditionText (student))
对于条件判断,我们还可以使用求值定界符,对上面的进行如下改写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <script id="templ4" type="text/x-dot-template" > <div > 姓名:{{=it.name}}</div > <div > 成绩:{{=it.score}}</div > {{ if (it.score <60 ) { }} <div>等级:不及格</div> {{ } else if (it.score <70 ) { }} <div>等级:及格</div> {{ } else if (it.score <80 ) { }} <div>等级:良好</div> {{ } else if (it.score <90 ) { }} <div>等级:优秀</div> {{ } else if (it.score <100 ) { }} <div>等级:棒极了</div> {{ } else { }} <div>等级:数据有误</div> {{ } }} </script>
谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里
模板定界符(doT新增功能) 在1.0.0之后的版本,doT加入的局部模板的功能,我们在模板中还可以定义一个局部模板。在主模板和子模板中我们都可以通过it变量引用到传入的对象。
<script id="templ6" type="text/x-dot-template"> // 定义主模板 {{##def.father: <div>主模板:{{=it.name}}</div> 子模板1:{{#def.child1}} 子模板2:{{#def.child2}} #}} // 编译时输入主模板 {{#def.father}} {{=it.html}} </script>
首先通过两个#定义一个编译的需要引入局部模板的主模板def.father,在它里面定义了两个子模板def.child1和def.child2,然后通过一个#在编译时输入我们的主模板。如果没有这段输入代码,那么最后在编译时doT不会帮我们输出主模板的。
var dataPart = { "name" :"Corner" , "age" :31 , "html" :"<div style='background: #f00; height: 30px; line-height: 30px;'>html元素</div>" };var defPart = { "child1" :"<div>{{=it.name}} who?</div>" , "child2" :"<div>{{=it.name}} how?</div>" };var partText = doT.template ($("#templ6" ).html (), undefined , defPart); $("body" ).html (partText (dataPart));
在JS中我们首先定义需要传入的数据,然后定义一个子模板的对象。这个对象中包含了我们在模板中定义的两个子模板的名称和内容,在子模板内容中,我们还是通过it变量引用到传入的对象。然后在生成模板函数时我们将子模板的对象一起传给template。