掌握js模板引擎

來源:互聯網
上載者:User

標籤:情況   lstat   大括弧   地球   lis   文章   hello   下載   .com   

最近要做一個小項目,不管是使用angularjs還是reactjs,都覺得大材小用了。其實我可能只需要引入一個jquery,但想到jquery對dom的操作,對於早已習慣了雙向繫結模式的我,何嘗不是一種痛苦。

聽過這樣一句話:“技術沒有缺席,只有姍姍來遲”,很多技術自己不知道,並非沒有。今天我想介紹的就是一個簡單的js模板引擎artTemplate,讓我們揚帆起航吧~

一、概述

artTemplate 是新一代 javascript 模板引擎,它採用先行編譯方式讓效能有了質的飛躍,並且充分利用 javascript 引擎特性,使得其效能無論在前端還是後端都有極其出色的表現。

二、我的痛點

我們先來看一段代碼,當我用ajax從後台拿到一堆json資料,要填充進頁面的時候,可能會這麼做:

123456789101112 $.ajax({ type: ‘GET‘, url: ‘/server/list.json‘, success: function(data) { var lists = ‘‘; for(var i=0;i<data.content.rows.length;i++){ lists += ‘<li><div class="lititle">‘+data.content.rows[i].leaveRuleName+‘(共計 ‘+data.content.rows[i].durationStr+‘)</div><div class="timer"><span>開始時間:‘+data.content.rows[i].startTime+‘</span><span>結束時間:‘+data.content.rows[i].endTime+‘</span></div><div class="btns"><p><a href="#" class="button button-round blue">‘+data.content.rows[i].customApprovalStatus+‘</a></p></div><div class="info">剛剛申請</div></li>‘; } $(‘#myList‘).append(lists); }, error: function(xhr, type) {//此處省略}})

 

html代碼:

1 <ul class="list-container" id="myList"></ul>

 

這段代碼,功能上可能並沒有什麼問題。但是我們來看lists變數,這裡面的資訊已經爆炸了,html結構以及data填充,寫完我就不想維護了。

正應了那句話:“此時我寫的代碼,只有我和天知道。半個月後,恐怕只有天知道了!”

三、處理痛點

這豈止是一場噩夢,簡直就是在挖坑埋雷??。好了,不再矯情了,我們換artTemplate來試試,代碼可能是這樣:

注意:記得提前引入template.js哦~

 

12345678 $.ajax({ type: ‘GET‘, url: ‘/server/list.json‘, success: function(data) { $(‘#myList‘).append(template(‘myListTpl‘, { lists: data.content.rows})); }, error: function(xhr, type) {//此處省略}})

 

html代碼:

12345678910111213141516 <script type="text/html" id="myListTpl"> {{each lists}} <li data-id="{{$value.id}}"> <div class="lititle">{{$value.overtimeRuleName}}(共計 {{$value.durationStr}})</div> <div class="timer"> <span>開始時間:{{$value.startTime}}</span> <span>結束時間:{{$value.endTime}}</span> </div> <div class="btns"> <p><a href="#" class="button button-round {{!$value.isEnsure?‘blue‘:($value.isEffective?‘green‘:‘red‘)}}">{{!$value.isEnsure?‘待確認‘:($value.isEffective?‘已確認‘:‘已失效‘)}}</a></p> </div> <div class="info">{{$value.applyTime | timeFormat}}申請</div> </li> {{/each}}</script><ul class="list-container" id="myList"></ul>

 

注意:script中的type=”text/html”

這段代碼很清晰,我們建立了myListTpl作為模板,裡面的html結構清晰,變數包在了雙大括弧中。那麼lists中的值是怎麼來的,細心的你可能看到了這個:

1 $(‘#myList‘).append(template(‘myListTpl‘, { lists: data.content.rows}));

 

對,我們用template去先行編譯模板,同時將資料塞進了lists中。就這樣,js中不需要很複雜的邏輯,html也儲存了原有的結構。

~嗡~嗡,嗯,整個世界都清靜了!

四、用法樣本

artTemplate用起來很簡單,我們來逐一舉例說明:

1.template(id,data),向id模板傳入資料。

12345678 <script id="test" type="text/html"><h1>{{title}}</h1><ul> {{each list as value i}} <li>索引 {{i + 1}} :{{value}}</li> {{/each}}</ul></script>

 

js代碼:

123456 var data = { title: ‘標籤‘, list: [‘文藝‘, ‘部落格‘, ‘攝影‘, ‘電影‘, ‘民謠‘, ‘旅行‘, ‘吉他‘]};var html = template(‘test‘, data);document.getElementById(‘content‘).innerHTML = html;

 

2.template.compile(source,options),先行編譯模板資料。

1234567891011121314 <script>var source = ‘<ul>‘+ ‘{{each list as value i}}‘+ ‘<li>索引 {{i + 1}} :{{value}}</li>‘+ ‘{{/each}}‘+ ‘</ul>‘; var render = template.compile(source);var html = render({ list: [‘攝影‘, ‘電影‘, ‘民謠‘, ‘旅行‘, ‘吉他‘]}); document.getElementById(‘content‘).innerHTML = html;</script>

 

上面兩種方式,屬於簡單的資料渲染,實際應用中我們可能會碰到比較複雜的操作,下面細說。

3.template.helper(name,callback),在模板中使用自訂方法。
某種情況下,我們需要對資料做一下預先處理,類似angularjs中的filter操作,那怎麼辦呢?

123 <script id="test" type="text/html">{{time | timeFormat}}</script>

 

1234 template.helper(‘timeFormat‘,function(date){ var result = Common.formateTime(date); return result;});

如上所示,我們調用了template.helper方法,將自訂方法放在回呼函數中,那麼資料是不是可以進行處理了呢。這裡我的情境是對時間資料做了格式化處理,我希望他顯示成“1小時前,剛剛”之類的文案。

4.template.config(name,value),更改引擎的預設配置。

5.include可嵌套子模板。

123456789101112 <div id="content"></div><script id="test" type="text/html"><h1>{{title}}</h1>{{include ‘list‘}}</script><script id="list" type="text/html"><ul> {{each list as value i}} <li>索引 {{i + 1}} :{{value}}</li> {{/each}}</ul></script>

 

js代碼:

123456 var data = {title: ‘嵌入子模板‘,list: [‘文藝‘, ‘部落格‘, ‘攝影‘, ‘電影‘, ‘民謠‘, ‘旅行‘, ‘吉他‘]};var html = template(‘test‘, data);document.getElementById(‘content‘).innerHTML = html;

 

重點在於:

1 {{include ‘list‘}}

 

將id為list的模板包含進來,很簡單,這裡就不細說了。

6.轉義

12345 <div id="content"></div><script id="test" type="text/html"><p>不轉義:{{#value}}</p><p>預設轉義: {{value}}</p></script>

 

js代碼:

12345 var data = { value: ‘<span style="color:#F00">hello world!</span>‘};var html = template(‘test‘, data);document.getElementById(‘content‘).innerHTML = html;

 

我們只需要加上“#”號,模板預設就不轉義啦。

7.在頁面上列印你的資料。
當然,你還可以這麼玩:

123 <script id="test" type="text/html">{{print a b c}}</script>

 

js代碼:

12345678 var html = ‘‘;var data = {a: ‘hello‘,b: ‘--world‘,c: ‘--!!!‘};html = template(‘test‘, data);document.write(html);

 

基本用法就這些了,是不是覺得很簡單呢,那就趕快試試吧!

五、原理剖析

當然,我們並不會只停留在會用的層次上面,模板引擎又是如何工作的呢?

artTemplate 模板編譯器會根據一些簡單的規則提取好所有模板變數,聲明在渲染函數頭部,這個函數類似:

12345678910 var render = function($data){var content = $data.content,$out = ‘‘;$out += ‘<h3>‘;if(typeof content === ‘string‘){$out += content;}$out += ‘</h3>‘;return $out;};

 

這個自動產生的函數就如同一個手工編寫的 javascript 函數一樣,同等的執行次數下無論 CPU 還是記憶體佔用都有顯著減少,效能近乎極限。

值得一提的是:artTemplate 很多特性都基於先行編譯實現,如沙箱規範與自訂文法等。

雖然每個引擎從模板文法、文法解析、變數賦值、字串拼接的實現方式各有所不同,但關鍵的渲染原理仍然是動態執行 javascript 字串。

嗯,點到為止吧。如果想深入瞭解,去下載個template.js,看看源碼吧。

六、負荷測試與調試


在 chrome 下渲染效率測試中分別是知名引擎 Mustache 與 micro tmpl 的 25 、 32 倍。
除了效能優勢外,調試功能也值得一提。模板調試器可以精確定位到引發渲染錯誤的模板語句,解決了編寫模板過程中無法調試的痛苦,讓開發變得高效,也避免了因為單個模板出錯導致整個應用崩潰的情況發生。樣本如下:

12345678 <script id="test" type="text/html"><ul>{{each list}}{{/each}} {{window.alert=null}}</ul></script>

 

js代碼:

123 var html = ‘‘;html = template(‘test‘, {});document.write(html);

 

list變數並沒有賦值,模板引擎會將錯誤拋出,方便定位與查錯。

七、意外收穫

原本我以為artTemplate會是最快的,結果又發現了doT,很好,你已經成功引起了我的注意。

正如大家所見,js模板引擎五花八門,如果每個引擎寫一篇文章,我想幾年內我應該不用幹其他事了(我才不會這麼無聊呢??)。so,不要糾結到底使用哪個模板引擎。請記住,適合自己的才是最好的。

八、總結

按照學習思路,從上到下有了這篇文章。之所以想要詳細的去寫一篇關於模板引擎的文章,主要是想彌補心裡的內疚。其實早在2014年我就有聽說過artTemplate,但卻只止步於聽過的程度。

當地球人都在用的時候,我還沒有開始,當大家已經去追逐天邊的雲彩,我才反應過來。

血淋淋的教訓,謹以此獻給和我有同樣遭遇以及感受的人們,任何時間請不要停下學習的腳步,哪怕晚了,但至少你努力過。

掌握js模板引擎

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.