模板引擎doT.js用法详解(HTML模板引擎)
作为一名前端攻城师,经常会遇到从后台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>
效果图: