doT學習(一)之語法


簡介

創建搜索最快和簡潔的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 和瀏覽器同樣適用。

doT 模板

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM