簡介
創建搜索最快和簡潔的JavaScript模板函數,強調V8和nodejs下的性能,它在nodejs和瀏覽器上都顯示了很好的性能。
dot.js速度快,體積小,沒有依賴關系,源js代碼只有140行
特性
-
無依賴
-
極其快速
-
自定義定界符 (custom delimiters)
-
運行時求值 (runtime evaluation)
-
運行時插值 (runtime interpolation)
-
編譯時求值 (compile-time evaluation)
-
支持局部模板
-
支持條件語句
-
數組迭代器
-
編碼
-
控制空白字符 - 全去或保留
-
流媒體友好
-
輕邏輯或者重邏輯,由你決定
doT.js詳細使用介紹
安裝方法
-
用於瀏覽器引入
javascript 文件:
<script type="text/javascript" src="doT.js"></script>
自代碼中使用
<script type="text/x-dot-template"></script>
-
用於 Node.js
如果你打算在 Node.js 中使用 doT,可以通過 npm 安裝 doT
npm install dot
在代碼中使用require('dot')
調用方式
doT渲染模板分為2個階段,這一點從它的使用方法中也能看出來:
// 1. 編譯模板函數
var tempFn = doT.template("<h1>Here is a sample template {{=it.foo}}</h1>"); // 2. 渲染模板函數
var resultText = tempFn({foo: 'with doT'});
這一點是與其他主流的模板引擎不同的。 在compile階段,可以依賴其他模板文件,緩存模板等操作。還可以傳入參數,通過條件判斷生成模板內容。 在頁面載入或是服務器啟動時,根據一些環境變量或其他條件預先編譯模板,可以進
一步提高模板渲染是的效率。
doT.template方法的第2個參數為配置項,第3個參數為編譯時可接收的參數,參數在模板中被默認存儲在def對象下,具體用法在{{#}}語法中介紹。
doT.template方法返回值為function類型:tempFn,tempFn接收的參數是模板渲染時可傳入的數據(與前面編譯時的數據不是同一份數據)。該數據在模板中被默認存儲在it對象下具體用法在{{}}和{{=}}等語法中都會介紹。
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', strip: true, append: true, selfcontained: false };
如果你想用自己的定界符,可以修改 doT.templateSettings 中的正則表達式。
這是默認的定界符列表:
-
{{= }} 用於插值
-
{{ }} 用於求值
-
{{~ }} 數組迭代
-
{{? }} 條件語句
-
{{! }} 用於編碼求值
-
{{# }} 用於編譯時求值/引入和局部模板
-
{{## #}} 用於編譯時定義
其他說明
varname
: 模板數據引用變量名
默認情況,模板中的數據必須用 'it' 作為引用。修改設置中的 'varname',可以改變默認的變量名。 例如,你可以把 'varname' 設置成 "foo, bar",就可以傳2個數據實例,通過 foo 和 bar 與模板建立關聯。
strip
: 控制空白字符,true
:全部去掉空格;false
:保留空格
append
: 性能優化設置
通過它調整性能,根據使用的 javascript 引擎和模板的大小,append 設置成 false,可能會產生更好的效果。
- selfcontained:依賴設置
如果 'selfcontained' 為 true,doT 將毫無依賴的產生函數。通常,doT 都是無依賴的,除非用到編碼時,encodeHTML 會被加入。 如果 'selfcontained' 為 true,模板需要編碼,encodeHTML 方法將被引入生成模板的函數中。
doT.template - 模板編譯函數
調用此函數把你的模板編譯成一個方法。
function(tmpl, c, def)
-
tmpl - 模板正文
-
c - 自定義編譯設置,如果為 null,用到 doT.templateSettings
-
def - 編譯時求值的數據(與前面編譯時的數據不是同一份數據)
默認,產生的方法有一個參數 - data - 命名為 'it' 。修改 doT.templateSettings.varname,可以改變參數的名字和個數。
實例
插值(evaluation)
用法:{{= }},輸出表達式,{{= }} 將其中的內容直接輸出到html中。其中可以是在{{ }}中定義的變量、通過函數傳入在it中的變量、也可以是全局變量、甚至可以是一個立即執行的function的返回結果。 可以簡單的理解為可以獲取特定作
用於下變量的單行js語句
// 模板字符串:
{{ it.a = 1; a = 2; }} {{= it.a}} it.a = 1 {{= a}} a = 2 {{= window}} window = [object Window] {{= (function(){return 123})()}} function(){return 123})() = 123
創建模板,默認情況下,模板中的數據用it
作為引用,可修改配置中的varname
來改變變量名;
<script type="text/x-dot-template" id="testTpl">
<div>{{= it.msg }}</div>
<div>{{= it.code }}</div>
</script>
使用:
var message = { msg: 'Hello world.', code: 200 }; //使用doT.template(tplText)函數,tplText為模板文本
var tpl = doT.template($("#testTpl").text()); //某些瀏覽器可能會取不到模板內容,可用$("#testTpl").html() //傳入數據獲取html
var html = tpl(message); console.log(html);
結果輸出:
<div class="msg">Hello world.</div> <div class="code">200</div>
求值(evaluate)
用法:{{ }}
,可在表達式中使用js
腳本,代碼片段,{{ }} 的用法非常靈活,里面可以直接寫js語句。定義的變量可以直接在{{= }}中調用。也可以調用通過tempFn傳入的數據(數據默認放在it對象內)。
// 模板字符串:
{{ var a = 1; it.a = a + 1; }} {{= a}} // a 輸出 1
{{= it.a}} // it.a 輸出 2
也可以定義函數。並在其他的{{}} 區塊內調用:
// 模板字符串:
{{ function fn() { return 123 } }} {{= fn()}} // fn 輸出 123
也可以直接運行匿名函數 {{ (function() { it.b = 123 })(); }} {{= it.b}} // it.b通過直接執行的匿名函數賦值為123
{{}}中的代碼塊隨時可以被打斷,插入dom片段等html內容:
// 模板字符串:
{{ var a = 3; if(a > 2) { }} a的值大於2 {{ } else { }} a的值小於2 {{ } }}
此外,{{}}中也可以直接調用全局對象下的函數或變量。可以以此特點實現比較復雜的功能(通過專用的命名空間給doT模板提供一些過濾器等特色的支持等)。
注意:如果在tempFn函數的調用中不傳參數或者傳入的是undefined等空對象,則doT不會實例化it對象。此時在{{}}中賦值的it對象的值,{{=}}中無法拿到(js的值引用問題)。
創建模板:
<script type="text/x-dot-template" id="testTpl2"> {{ if (it.status == true) { }} <div class="success">操作成功</div> {{ } else { }} <div class="error">操作錯誤</div> {{ } }} </script>
使用:
var result = { status: true, error: '' }; var tpl = doT.template($("#testTpl2").text()); var html = tpl(result); console.log(html);
結果輸出:
<div class="success">操作成功</div>
條件語句(conditional)
用法:{{? }},{{?}}標簽必須成對出現,起始標簽中寫入判斷條件,並以另外一個{{?}}標簽為結束。該標簽和下面的{{~}}是{{if for}}的語法糖。
如上面的:
// 模板字符串:
{{ var a = 3; if(a > 2) { }} a的值大於2 {{ } else { }} a的值小於2 {{ } }}
可以用本標簽簡寫為:
// 模板字符串:
{{ var a = 3; }} {{? a>2}} a的值大於2 {{?? true}} a的值小於2 {{?}}
在上個 求值(evaluate) 例子中的模板恰好是條件判斷,我們可以用{{? }}
改寫模板以達到一樣的效果:
<script type="text/x-dot-template" id="testTpl2"> {{? it.status == true }} <div class="success">操作成功</div> {{?? }} <div class="error">操作錯誤</div> {{? }} </script>
使用方法參考求值(evaluate)例子,最后輸出html
是一樣的。
數組迭代(iterate)
用法:{{~ }},循環,
{{~}}標簽必須成對出現,起始標簽中寫入對數組遍歷的變量賦值:{{~it.array :value:index}},並以另外一個{{~}}標簽為結束。
創建模板:
<script type="text/x-dot-template" id="testTpl3"> {{~ it.list:item:index }} <tr>
<td>{{= index + 1 }}</td>
<td>{{= item.name }}</td>
<td>{{= item.email }}</td>
</tr> {{~ }} </script>
使用:
var data = { status: true, msg: 'success', list: [{ id: 1, name: 'zhangsan', email: 'zhangsan@lwhweb.com' }, { id: 2, name: 'lisi', email: 'lisi@lwhweb.com' }] }; var tpl = doT.template($("#testTpl3").html()); var html = tpl(data); console.log(html);
結果輸出:
<tr> <td>1</td> <td>zhangsan</td> <td>zhangsan@lwhweb.com</td> </tr> <tr> <td>2</td> <td>lisi</td> <td>lisi@lwhweb.com</td> </tr>
編碼插值
用法:{{! }} encode 轉義,{{! }} 會將其中的內容中特定字符進行轉義,如:{{! location.href}}
// 數據源
{"uri":"http://jq22.com/?keywords=Yoga"} // 區域
<div id="encode"></div>
// 模版
<script id="encodetmpl" type="text/x-dot-template"> Visit {{!it.uri}} {{!it.html}} </script>
// 調用方式
var dataEncode = {"uri":"http://jq22.com/?keywords=Yoga","html":"<div style='background: #f00; height: 30px; line-height: 30px;'>html元素</div>"}; var EncodeText = doT.template($("#encodetmpl").text()); $("#encode").html(EncodeText(dataEncode));
編譯時變量定義
用法:{{## #}}
{{## #}}有兩種賦值方式:使用=賦值和使用:賦值。二者的區別是,=賦值時,右側是一個js的表達式。可以是函數定義、真值判斷、字符串等等,:賦值時,緊跟:之后的所有內容,都被當做靜態模板直接賦值給變量:
// 模板字符串:
{{## def.array = [1,2,3,4] #}} {{#def.array[0]}} 的值是 1 {{## def.array2:[1,2,3,4] #}} {{#def.array2[0]}} 的值是 [ // array2是字符串的:”[1,2,3,4]”,所以第0位是 [
編譯時載入代碼片段
用法:{{# }}
編譯時載入代碼片段、文件類似於宏編譯,在compile階段,將對應的變量或文件內容插入指定的位置傳入的參數默認在對象def中。此外,通過{{## #}}定義的變量,也都是在def對象中的用法與{{}}基本一致,只是生效的階段不同。
編譯時包含模板和編譯時定義綜合使用
用法:{{# }}
和{{## #}}
創建模板:
<script type="text/x-dot-template" id="testHeaderTpl">
<h2>標題:{{= it.title }}</h2>
</script>
<script type="text/x-dot-template" id="testPageTpl5">
<h2>以下使用'testHeaderTpl'模板內容:</h2> {{#def.header }} {{= it.content }} {{#def.injectIntoHeader || '' }} </script>
<script type="text/x-dot-template" id="testBodyTpl">
<h2>工作內容:</h2> {{#def.body }} <h2>以下是編譯時定義</h2> {{##def.injectIntoHeader: <div>截止時間:{{= it.dealine }} </div> #}} </script>
使用:
var work = { title: '完善項目一需求提取', content: '請研發部爭取在月底前提取項目一需求', dealine: '2017-11-25 23:00' }; var def = { header: $('#testHeaderTpl').text(), body: $('#testPageTpl5').text() }; var tpl = doT.template($("#testBodyTpl").html(), null, def); var html = tpl(work); console.log(html);
結果輸出:
<h2>工作內容:</h2> <h2>以下使用'testHeaderTpl'模板內容:</h2> <h2>標題:完善項目一需求提取</h2> 請研發部爭取在月底前提取項目一需求 <div>截止時間:2017-11-25 23:00 </div> <h2>以下是編譯時定義</h2>
額外
1、瀏覽器執行到
<script id="encodetmpl" type="text/x-dot-template">
......
</script>
不會解析,因為瀏覽器“不認識它”,這個是在我們調用模版函數的時候才渲染執行的
2、dot模版會被編譯成函數
3、根據前面所有的介紹我們可以知道,dot模版渲染分為兩個階段,編譯和渲染,因此它的用法也要分為兩個層面,一個是編譯一個是渲染
編譯時使用dot.template(參數1,參數2,參數3),着重說參數3,參數3接受編譯時傳入的參數,默認存儲在def對象中, 並且{{## # }}、{{# }}在編譯時使用,{{## # }}定義的變量存儲在def中
渲染時使用dot.template()返回的函數,假如是temp(參數4),參數4接受渲染時傳入的參數,默認存儲在it對象中,並且{{= }}、{{ }}、{{? }}、{{~ }}、{{! }}在渲染時使用,{{ }}定義的變量存儲在it中
參考
Github地址:https://github.com/olado/doT
精巧快速的 JavaScript 模板引擎,Node.js 和瀏覽器同樣適用。