doT作为一个模板渲染引擎来说,无论是在 nodejs 还是在浏览器,性能都相当优越,不同于 vue,react 的 mv*框架,它的功能很简单,输入模板字符串,输出渲染后的 html

在 apicloud 开发时,由于不是单纯的 spa 应用,每个 window 相当于一个 html,所以尽量不采用 vue,react 等来渲染页面,再说双向绑定,dom 操作比较少,所以使用 doT 来渲染速度会略胜一筹

遍历对象

<!-- 设备列表 -->
<ul id="list"></ul>
<!-- 设备item模板 -->
<script id="listTpl" type="text/x-dot-template">
{{ for (var k in it) { }}
<li>{{= it[k]['name'] }}</li>
{{ } }}
</script>
<script>
var units = {
1: { name: 'unit1' },
2: { name: 'unit2' },
3: { name: 'unit3' },
};
var compile = doT.template(document.getElementById('listTpl').innerHTML);
var unitList = document.getElementById('list');
unitList.innerHTML = compile(units);
</script>

遍历数组

<!-- 设备列表 -->
<ul id="list"></ul>
<!-- 设备item模板 -->
<script id="listTpl" type="text/x-dot-template">
{{~it: value:index }}
<li>{{= value['name'] }}</li>
{{~}}
</script>
<script>
var units = [{ name: 'unit1' }, { name: 'unit2' }, { name: 'unit3' }];
var compile = doT.template(document.getElementById('listTpl').innerHTML);
var unitList = document.getElementById('list');
unitList.innerHTML = compile(units);
</script>

嵌套模板

<ul id="list"></ul>
<script id="listTpl" type="text/x-dot-template">
{{#def.header }}
{{##def.snippet:
<div>{{= it.content }}</div> #}}
{{#def.snippet}}
</script>
<script id="headerTpl" type="text/x-dot-template">
<h2>{{= it.header }}</h2>
</script>
<script>
var def = {
header: document.getElementById('headerTpl').innerText,
};
var data = {
header: 'header',
content: 'content',
};
var compile = doT.template(
document.getElementById('listTpl').innerHTML,
undefined,
def
);
document.getElementById('list').innerHTML = compile(data);
</script>

html 字符串转义

<div id="content"></div>
<script id="uriTpl" type="text/x-dot-template">
{{! "<h1>2</h1>" }}
</script>
<script src="./doT.min.js"></script>
<script>
var data = {
uri: 'http://www.baidu.com',
};
var compile = doT.template(document.getElementById('uriTpl').innerHTML);
document.getElementById('content').innerHTML = compile(data);
</script>

条件表达式

<div id="content"></div>
<script id="condTpl" type="text/x-dot-template">
{{? it.name }}
<h1>i love you {{= it.name }}</h1>
{{?? it.age == 24 }}
<h1>number is 24</h1>
{{??}}
<h1>you got nothing</h1>
{{?}}
</script>
<script src="./doT.min.js"></script>
<script>
var data = {
name: 'kobe',
age: 24,
};
var compile = doT.template(document.getElementById('condTpl').innerHTML);
document.getElementById('content').innerHTML = compile(data);
</script>

上面代码转为 js 语法是

if (data['name']) {
// i love you kobe
} else if (data['age'] == 24) {
// number is 24
} else {
// you got nothing
}

insertAdjacentHTML

element.insertAdjacentHTML(position, text);

position 有 4 个选项  beforebeginafterbeginbeforeendafterend

对应的位置

在使用过程中,比如列表追加,可以使用 insertAdjaceHTML 往列表后面拼接 html,避免每次都重新覆盖整个 html,例如上面的 for 循环例子

错误的写法

var newUnits = [{ name: 'unit4' }, { name: 'unit5' }, { name: 'unit6' }];
unitList.innerHTML += compile(newUnits);

正确的写法

var newUnits = [{ name: 'unit4' }, { name: 'unit5' }, { name: 'unit6' }];
unitList.insertAdjacentHTML('beforeend', compile(newUnits));