模板引擎doT.js用法详解
作为一名前端攻城师,经常会遇到从后台ajax拉取数据再显示在页面的情境,一开始我们都是从后台拉取再用字符串拼接的方式去更达到数据显示在页面!
<!-- 显示区域 --> <div id="testid"></div>
<script type="text/javascript">
var testjson={"name":"张三","age":31,"fun":"吃东西"};//假设是后台拉取的数据
document.getElementById("testid").innerHTML="<p>"+
"<span>姓名:"+testjson.name+"</span>"+
"<span>年龄:"+testjson.age+"</span>"+
"<span>爱好:"+testjson.fun+"</span>"+
"</p>";
</script>
这样不但写起来很麻烦,必须保证每一个引号正确,特别是如果数据里还有单双号的时候,还要注意单双引号混用,或者用转义,效率很低下,很容易出错,后面有接触到知道有JS模板引擎像百度的baiduTemplate(百度)\artTemplate(腾讯)\juicer(淘宝)\doT\ tmpl\ handlebars\ easyTemplate\ underscoretemplate \ mustache \kissytemplate,在网上几翻选择,我还是选择了doT.js,它的大小只有4KB,渲染性能很好,而且直接支持原生的写法,不用依赖别的库。下面就让我们来一起了解下它的用法,让数据渲染飞起来吧!
首先准备工作,引入doT.js:
<script type="text/javascript" src="js/jquery-1.11.0.js"></script> <script type="text/javascript" src="js/doT.js"></script>
1、最常规用法{{=it.attr}}
<!-- 要显示的区域 --> <div id="testid"></div> <script type="text/x-dot-template" id="useType0">//模板存放区域 修改type类型,以免会被解析成js
<p>
<span>姓名:{{=it.name}}</span>
<span>年龄:{{=it.age}}</span>
<span>爱好:{{=it.fun}}</span>
</p>
</script> <!-- 引入js文件 --> <script type="text/javascript" src="doT.min.js"></script> <script> /*基本用法*/ var testjson={"name":"张三","age":31,"fun":"吃东西"},//定义要渲染数据,一般是从后台ajax拉取 tmpltxt=doT.template(document.getElementById("useType0").innerHTML);//生成模板方法 document.getElementById("testid").innerHTML=tmpltxt(testjson);//数据渲染 </script>
得到的结果如下:
2、循环数组{{~}}
<!-- 要显示的区域 -->
<div id="testid"></div>
<!-- 模板存放区域 修改type类型,以免会被解析成js -->
<script type="text/x-dot-template" id="useType0">
<ul>
{{~it:value:index}}
<li><span>姓名:{{=value.name}}</span><span>年龄:{{=value.age}}</span><span>爱好:{{=value.fun}}</span></li>
{{~}}
</ul>
</script>
<!-- 引入js文件 -->
<script type="text/javascript" src="doT.min.js"></script>
<script>
/*基本用法*/
var testjson=[
{"name":"张三","age":31,"fun":"吃东西"},
{"name":"李四","age":24,"fun":"上网"},
{"name":"王五","age":70,"fun":"散步,跑步"}
],//定义要渲染数据,一般是从后台ajax拉取
tmpltxt=doT.template(document.getElementById("useType0").innerHTML);//生成模板方法
document.getElementById("testid").innerHTML=tmpltxt(testjson);//数据渲染
</script>
得到的结果如下:
3、条件渲染{{?}}{{??}},相当于原生的if else if
<!-- 要显示的区域 -->
<div id="testid"></div>
<!-- 模板存放区域 修改type类型,以免会被解析成js -->
<script type="text/x-dot-template" id="useType0">
<ul>
{{~it:value:index}}
{{?!value.age}}
<li><span>姓名:{{=value.name}}</span><span>年龄:年龄数据缺失</span><span>爱好:{{=value.fun}}</span></li>
{{??!value.fun}}
<li><span>姓名:{{=value.name}}</span><span>年龄:{{=value.age}}</span><span>爱好:无趣的人</span></li>
{{??}}
<li><span>姓名:{{=value.name}}</span><span>年龄:{{=value.age}}</span><span>爱好:{{=value.fun}}</span></li>
{{?}}
{{~}}
</ul>
</script>
<!-- 引入js文件 -->
<script type="text/javascript" src="doT.min.js"></script>
<script>
/*基本用法*/
var testjson=[
{"name":"张三","age":31,"fun":"吃东西"},
{"name":"李四","fun":"上网"},
{"name":"王五","age":70}
],//定义要渲染数据,一般是从后台ajax拉取
tmpltxt=doT.template(document.getElementById("useType0").innerHTML);//生成模板方法
document.getElementById("testid").innerHTML=tmpltxt(testjson);//数据渲染
</script>
得到的结果如下:
4、编码渲染{{!}},主要是为了防止代码注入以保障安全,如传入一个HTML片段或js片段,它会以字符串的形式渲染
<!-- 要显示的区域 -->
<div id="testid"></div>
<!-- 模板存放区域 修改type类型,以免会被解析成js -->
<script type="text/x-dot-template" id="useType0">
<ul>
{{~it:value:index}}
{{?value.bz}}
<li><span>姓名:{{=value.name}}</span><span>年龄:{{=value.age}}</span><span>爱好:{{!value.html}}</span></li>
{{??}}
<li><span>姓名:{{=value.name}}</span><span>年龄:{{=value.age}}</span><span>爱好:{{=value.html}}</span></li>
{{?}}
{{~}}
</ul>
</script>
<!-- 引入js文件 -->
<script type="text/javascript" src="doT.min.js"></script>
<script>
/*基本用法*/
var testjson=[
{"name":"张三","age":31,"html":"<b>呵呵</b>","bz":true},
{"name":"李四","age":24,"html":"<b>哈哈</b>","bz":false}
],//定义要渲染数据,一般是从后台ajax拉取
tmpltxt=doT.template(document.getElementById("useType0").innerHTML);//生成模板方法
document.getElementById("testid").innerHTML=tmpltxt(testjson);//数据渲染
</script>
得到的结果如下:
5、支持共用模块定义{{##def.}}定义,{{#def.}}引用模块
<!-- 要显示的区域 -->
<div id="testid"></div>
<!-- 模板存放区域 修改type类型,以免会被解析成js -->
<script type="text/x-dot-template" id="useType0">
<!-- 模块定义0 -->
{{##def.togeter0:
<li><span>姓名:{{=value.name}}</span><span>年龄:{{=value.age}}</span><span>爱好:{{!value.html}}</span></li>
#}}
<!-- 模块定义1 -->
{{##def.togeter1:
<li><span>姓名:{{=value.name}}</span><span>年龄:{{=value.age}}</span><span>爱好:{{=value.html}}</span></li>
#}}
<ul>
{{~it:value:index}}
{{?value.bz}}
<!-- 引用模块0 -->
{{#def.togeter0}}
{{??}}
<!-- 引用模块1 -->
{{#def.togeter1}}
{{?}}
{{~}}
</ul>
</script>
<!-- 引入js文件 -->
<script type="text/javascript" src="doT.min.js"></script>
<script>
/*基本用法*/
var testjson=[
{"name":"张三","age":31,"html":"<b>呵呵</b>","bz":true},
{"name":"李四","age":24,"html":"<b>哈哈</b>","bz":false}
],//定义要渲染数据,一般是从后台ajax拉取
tmpltxt=doT.template(document.getElementById("useType0").innerHTML);//生成模板方法
document.getElementById("testid").innerHTML=tmpltxt(testjson);//数据渲染
</script>
得到的结果如下:
注:模块定义也可以一个json数据定义,再在生成模板函数函数的时候传入即可,示例如下,其中tmpljson就是在外面以json定义的模块:
<!-- 要显示的区域 -->
<div id="testid"></div>
<!-- 模板存放区域 修改type类型,以免会被解析成js -->
<script type="text/x-dot-template" id="useType0">
<!-- 模块定义0 -->
{{##def.togeter0:
<li><span>姓名:{{=value.name}}</span><span>年龄:{{=value.age}}</span><span>爱好:{{!value.html}}</span></li>
#}}
<!-- 模块定义1 -->
{{##def.togeter1:
<li><span>姓名:{{=value.name}}</span><span>年龄:{{=value.age}}</span><span>爱好:{{=value.html}}</span></li>
#}}
<ul>
{{~it:value:index}}
{{?value.bz===true}}
<!-- 引用模块0 -->
{{#def.togeter0}}
{{??value.bz===false}}
<!-- 引用模块1 -->
{{#def.togeter1}}
{{??}}
<!-- 引用传入的模块 -->
{{#def.testmode}}
{{?}}
{{~}}
</ul>
</script>
<!-- 引入js文件 -->
<script type="text/javascript" src="doT.min.js"></script>
<script>
/*基本用法*/
var testjson=[
{"name":"张三","age":31,"html":"<b>呵呵</b>","bz":true},
{"name":"李四","age":24,"html":"<b>哈哈</b>","bz":false},
{"name":"李四","age":24,"html":"<b>哈哈</b>"}
],//定义要渲染数据,一般是从后台ajax拉取
tmpljson={"testmode":"<li><span>姓名:{{=value.name}}</span><span>年龄:{{=value.age}}</span></li>"}//以json格式定义模块
tmpltxt=doT.template(document.getElementById("useType0").innerHTML,undefined,tmpljson);//生成模板方法,传入了json定义的模块
document.getElementById("testid").innerHTML=tmpltxt(testjson);//数据渲染
</script>
得到的结果如下:
6、用原生的循环,条件渲染,这也是doT.js的一大吸引我的特点
<!-- 要显示的区域 -->
<div id="testid"></div>
<!-- 模板存放区域 修改type类型,以免会被解析成js -->
<script type="text/x-dot-template" id="useType0">
<!-- 模块定义0 -->
{{##def.togeter0:
<li><span>姓名:{{=itz.name}}</span><span>年龄:{{=itz.age}}</span><span>爱好:{{!itz.html}}</span></li>
#}}
<!-- 模块定义1 -->
{{##def.togeter1:
<li><span>姓名:{{=itz.name}}</span><span>年龄:{{=itz.age}}</span><span>爱好:{{=itz.html}}</span></li>
#}}
<ul>
{{ for(var i=0;i<it.length;i++){ }}
{{ var itz=it[i]; }}
{{ if(itz.bz){ }}
<!-- 引用模块0 -->
{{#def.togeter0}}
{{ }else{ }}
<!-- 引用模块1 -->
{{#def.togeter1}}
{{ } }}
{{ } }}
</ul>
</script>
<!-- 引入js文件 -->
<script type="text/javascript" src="doT.min.js"></script>
<script>
/*基本用法*/
var testjson=[
{"name":"张三","age":31,"html":"<b>呵呵</b>","bz":true},
{"name":"李四","age":24,"html":"<b>哈哈</b>","bz":false}
],//定义要渲染数据,一般是从后台ajax拉取
tmpltxt=doT.template(document.getElementById("useType0").innerHTML);//生成模板方法
document.getElementById("testid").innerHTML=tmpltxt(testjson);//数据渲染
</script>
得到的结果如下:
7、嵌套循环(很常用)
先准备好存放内容得容器:<div id="category-goods"></div>
<!-- 必须加上type="text/x-dot-template" -->
<script id="category-goods-tmpl" type="text/x-dot-template">
{{~it:item:index}}
<div class="rxsp">
<div class="aui-pull-left">
<h3> {{= item.name }} 【索引: {{= index }} 】</h3>
</div>
<a class="aui-pull-right ">
查看更多
<span class="aui-iconfont aui-icon-right"></span>
</a>
</div>
<div class="aui-list-item-inner">
<div class="aui-row aui-row-padded">
{{~it[index].goods:item:j}}
<div class="aui-col-xs-6">
<img src="{{= item.logoimg }}" onclick="">
<p class="tit">{{= item.name }} </p>
<div class="aui-info" style="padding-top:0">
<div class="aui-info-item">
<span class="red">¥{{= item.price }}
</div>
</div>
</div>
{{~}}
</div>
</div>
{{~}}
</script>
<script type="text/javascript">
var goods_list = {
"list": [{
"id": "1",
"name": "衣服",
"goods": [{
"goods_id": "1",
"name": "衣服1",
"price": "100",
"logoimg": "http://image.diandodo.com/zhudianbao/Uploads/User/u1250000222/20160723/201607231342158687.png@250h_250w_1e_1c"
},
{
"goods_id": "2",
"name": "衣服2",
"price": "200",
"logoimg": "http://image.diandodo.com/zhudianbao/Uploads/User/u1250000222/20160723/201607231342158687.png@250h_250w_1e_1c"
}
]
},
{
"id": "2",
"name": "鞋子",
"goods": [{
"goods_id": "3",
"name": "鞋子1",
"price": "100",
"logoimg": "http://image.diandodo.com/zhudianbao/Uploads/User/u1250000222/20160723/201607231342158687.png@250h_250w_1e_1c"
},
{
"goods_id": "4",
"name": "鞋子2",
"price": "200",
"logoimg": "http://image.diandodo.com/zhudianbao/Uploads/User/u1250000222/20160723/201607231342158687.png@250h_250w_1e_1c"
}
]
}
]
};
// var tmpltxt = doT.template(document.getElementById("category-goods-tmpl").innerHTML);
// document.getElementById("category-goods").innerHTML = tmpltxt(goods_list.list); //数据渲染
var evalText = doT.template($("#category-goods-tmpl").html());
$("#category-goods").html(evalText(goods_list.list));
</script>
效果图:

出 处:http://www.cnblogs.com/zhao-yi
Git 地 址:https://github.com/ZhaoYis
个人博客:http://www.zhaoyis.com.cn
关于作者:主要从事基于.Net Framework平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

浙公网安备 33010602011771号