前端模板引擎doT.js的使用

3,031 阅读1分钟

前言

我们在做前端开发时,经常需要根据后台返回的json数据动态生成html并插入到页面中显示。最简单的方法就是通过jQuery去遍历数据拼接html,如以下:

<script>
    var data = {
        list: [{
            id: 1,
            name: 'zhangsan',
            email: 'zhangsan@lwhweb.com'
        }, {
            id: 2,
            name: 'lisi',
            email: 'lisi@lwhweb.com'
        }]
    };
    var html = '';
    $.each(data.list, function(index, item) {
        html += '<tr></tr>';
        html += '<td>' + item.id + '</td>';
        html += '<td>' + item.name + '</td>';
        html += '<td>' + item.email + '</td>';
        html += '</tr>'
    });
    $('#userList').empty();
    $('#userList').html(html); 
</script>

但是,这种通过拼接html的方式使用在比较简单的结构还好;如果结构比较复杂,拼接的时候还得注意引号之间的嵌套,而且代码维护起来也比较困难,代码可读性也差。因此使用模板引擎可以帮我们很好的避免这个问题。

常用的模板引擎有artTemplate、Jade、Mustache、doT.js、juicer等,此编文章仅介绍doT.js的使用。

介绍

doT模板引擎是一个最快速最简洁的JavaScript模板引擎,在浏览器端和Nodejs端都适用。它小巧快速并且没有任何依赖,所有代码才一百多行,压缩后才4k,非常的轻量。

配置

在doT文件中有一个templateSettings属性用来配置doT的定界符(官方文档这么称呼,我们可以理解为模板的语法),我们也可以手动修改使用自己的定界符,但是建议使用默认的:

doT.templateSettings = {
  evaluate:    /\{\{([\s\S]+?)\}\}/g,
  interpolate: /\{\{=([\s\S]+?)\}\}/g,
  encode:      /\{\{!([\s\S]+?)\}\}/g,
  use:         /\{\{#([\s\S]+?)\}\}/g,
  define:      /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,
  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.templateSettings中的正则。

以下是默认的分隔符列表:

  • {{ }}:用于求值(evaluate)

  • {{= }}:用于插值(interpolate)

  • {{! }}: 用于插值编码(encode)

  • {{# }}:用于编译时求值/包含局部模板(use)

  • {{## #}}:用于编译时定义(define)

  • {{? }}:用于条件语句(conditional)

  • {{~ }}:用于数组迭代(iterate)

基本语法

首先介绍一下doT模板中常用的定界符代表的使用和含义:

{{= }}    输出显示,默认变量名叫it (用于插值)
{{ }}     模板标记符 (用于求值)
{{? }}    条件分支,if条件的简写 (条件语句)
{{~ }}    条件语句(数组迭代)
{{! }}    编码后输出显示(用于编码求值)
{{# }}    用于编译时求值/引入和局部模板
{{## #}}  用于编译时定义

模板示例

    <!--赋值-->
    <script id="interpolationtmpl" type="text/x-dot-template">
        <div>{{=it.name}}</div>
        <div>dot框架</div>
    </script>
    
    <!--循环map-->
    <script id="evaluationtmpl" type="text/x-dot-template">
        {{ for(var prop in it) { }}
        <div>键:{{= prop }}对应的值:{{= it[prop] }}</div>
        {{ } }}
    </script>
    
    <!--数组对象-->
    <script id="arraystmpl" type="text/x-dot-template">
        {{~it.interests:value:index}}
        <div>下标:{{= index }}对应的值:{{= value }}!</div>
        {{~}}
    </script>
    
    <!--条件-->
    <script id="conditionstmpl" type="text/x-dot-template">
        {{? it.name }}
        <div>name存在时走到这里, {{=it.name}}!</div>
        {{?? !it.age === 0}}
        <div>age等于零时走到这里!</div>
        {{??}}
        You are {{=it.age}}
        {{?}}
    </script>

循环数组示例

数组

var allData = ['广州市', '深圳市', '珠海市', '汕头市', '佛山市', '韶关市', '河源市', '梅州市', '惠州市', '汕尾市', '东莞市', '中山市', '江门市', '阳江市', '湛江市', '茂名市', '肇庆市', '清远市', '潮州市', '揭阳市', '云浮市'];

Number把prop字符串,转成数字

<script id="dot_01" type="text/x-dot-template">
    <ul>
        {{ for(var prop in it) { }}
        <li class="nav-item" id="nav_{{=Number(prop)+1}}">{{= it[prop] }}</li>
        {{ } }}
    </ul>
</script>

条件语句示例

在模板中有时候我们需要对数据进行判断,进行不同的展示,这时我们就需要用到条件定界符。

<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>

对于条件判断,我们还可以使用求值定界符,对上面的进行如下改写:

<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>

项目中难点示例

{{=it[0].titlecn}}
{{=it[1].titlecn}}
{{=it[2].titlecn}}
{{=it[3].titlecn}}
{{=it[4].titlecn}}

图片渲染(三元判断)

<img src="{{=it[0].logo?it[0].logo:'img/kan/04.png'}}">

dot模板中使用方法

src="{{=setICon_opShowflag(value.opShowflag)}}"
{{=estriction(it[7].titlecn,19)}}