1. 程式人生 > >JavaScript模板引擎例項應用

JavaScript模板引擎例項應用

本文將舉例項向大家講解幾個常用模板引擎的簡單使用。

模板引擎示例演示地址

準備工作

演示資料:blog.json
結構:

{
    "list": [
        {
            "title": "這是title",
            "url": "http://www.cnblogs.com/52fhy/p/5271447.html",
            "desc": "摘要"
        },
        {
            "title": "這是title2",
            "url": "http://www.cnblogs.com/52fhy/p/4823390.html",
            "desc": "摘要"
        }]
}

html頁面:

<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
    <title>demo</title>
    <!--weui.css僅為快速的做出頁面,可刪除-->
    <link rel="stylesheet" href="static/weui.css"/>
    <script src="static/zepto.min.js"></script>
</head>
<body>
    <div class="weui_panel weui_panel_access">
        <!--內容展示區:實際演示將會去掉,使用js動態生成-->
        <div class="weui_panel_hd">文字組合列表</div>
        <div class="weui_panel_bd">
            <div class="weui_media_box weui_media_text">
                <h4 class="weui_media_title">標題一</h4>
                <p class="weui_media_desc">由各種物質組成的巨型球狀天體,叫做星球。星球有一定的形狀,有自己的執行軌道。</p>
            </div>
        </div>
        <!--/內容展示區-->
    </div>
    
<script type="text/javascript">
    $(function(){
        $.ajax({
            url: 'static/blog.json',
            type: 'get',
            dataType: 'json',
            success: function (response) {
                //後文主要改動的地方之一
                //這裡暫時為空
            },
            error: function (jqXHR, textStatus, errorThrown) {
                if (textStatus == 'timeout') {
                    alert('請求超時');
                    return false;
                }
                console.log(jqXHR.responseText);
            },
        });
    });
</script>
</body>

下文將講解使用ajax獲取資料並顯示到頁面的『內容展示區』。

  • 不使用模板

這種方式是大家見過或者使用最多的了:

模板
無需模板。

js程式碼
在success裡面加上程式碼:

var htmlList = '';
var data = response.list;

$.each(data, function(i,el) {
    htmlList +='<div class="weui_media_box weui_media_text">'+
        '<a href="'+ el.url +'" target="_blank"><h4 class="weui_media_title">'+ el.title +'</h4></a>'+
        '<p class="weui_media_desc">'+ el.desc +'</p>'+
    '</div>';
});

$('.js-blog-list').empty().append(htmlList);

程式碼裡明顯看到一大堆的拼接符號,顯得不是很優雅,不方便後期維護。

  • 簡單的模板引擎

這裡不需要引入第三方模板引擎外掛,自己寫一個:

/*
 * 實現簡單模板渲染功能  不支援物件巢狀
 * 不支援if等語句
*/
String.prototype.temp = function(obj) {
    return this.replace(/\$\w+\$/gi, function(matchs) {
        
        var returns = obj[matchs.replace(/\$/g, "")];       
        return (returns + "") == "undefined"? "": returns;
    });
};

記得放到頁面的js程式碼裡。

模板

<!--模板-->
<textarea class="js-tmp" style="display:none;">
    <div class="weui_media_box weui_media_text">
        <a href="$url$" class="" target="_blank">
            <h4 class="weui_media_title">$title$</h4>
        </a>
        <p class="weui_media_desc">$desc$</p>
    </div>
</textarea>
<!--/模板-->

變數使用$$佔位。

這裡的模板放在 <textarea> 中,一般情況設定其CSS樣式display:none來隱藏掉textarea。

還有一種方式是模板放在 <script> 中,設定type屬性為text/templatetext/html,用id標識:

<script id='test1' type="text/template">
<!-- 模板部分 -->

<!-- 模板結束 -->   
</script>

大家喜歡哪種就使用哪種。

js程式碼

var htmlList = '';
var data = response.list;
var htmlTemp = $("textarea.js-tmp").val(); //讀取模板內容

$.each(data, function(i,el) {
    htmlList += htmlTemp.temp(el); //模板渲染並生成最終內容
});

$('.js-blog-list').empty().append(htmlList);

程式碼量並不多,比較簡單。注意temp方法來源於String.prototype.temp

  • laytpl

上一篇文章也介紹過這個模板引擎,這裡不多介紹,大家可以去其官網看詳細資訊。

簡介:

laytpl官網 - 精妙的JavaScript模板引擎  http://laytpl.layui.com/
            
支援if等語句{{# if(){ //some code ... }}   {{# } }}

模版語法:
輸出一個普通欄位,不轉義html:   {{ d.field }}
輸出一個普通欄位,並轉義html:   {{= d.field }}
JavaScript指令碼: {{# JavaScript statement }}

使用前需要引入laytpl.js

<script src="laytpl/laytpl.js"></script>

模板

<!--模板-->
<textarea class="js-tmp" style="display:none;">
    <div class="weui_media_box weui_media_text">
        <a href="{{d.url}}" class="" target="_blank">
            <h4 class="weui_media_title">{{d.title}}</h4>
        </a>
        <p class="weui_media_desc">{{d.desc}}</p>
    </div>
</textarea>
<!--/模板-->

laytpl模板引擎使用{{d.變數}}表示變數。注意不要忘記了字首d.,任何情況都要加上。這也算是模板的一大特色。

js程式碼
js程式碼很簡單,這裡不全部複製過來了,僅顯示與簡單的模板引擎有區別的:

$.each(data, function(i,el) {
    //htmlList += htmlTemp.temp(el);
    htmlList += laytpl(htmlTemp).render(el);//模板渲染並生成最終內容
});

很簡單吧!註釋的那一行是簡單的模板引擎所用的程式碼,這裡進行對比。這裡不多做解釋。

  • underscore

underscore是個js工具庫,其種_.underscore()方法支援模板功能。

簡介:

Underscore.js(1.8.3) 
中文文件 http://www.css88.com/doc/underscore/
            
template_.template(templateString, [settings]) 
將 JavaScript 模板編譯為可以用於頁面呈現的函式, 對於通過JSON資料來源生成複雜的HTML並呈現出來的操作非常有用。

模板函式可以使用 <%= … %>插入變數, 也可以用<% … %>執行任意的 JavaScript 程式碼。 如果您希望插入一個值, 並讓其進行HTML轉義,請使用<%- … %>。 當你要給模板函式賦值的時候,可以傳遞一個含有與模板對應屬性的data物件 。 

如果您要寫一個一次性的, 您可以傳物件 data 作為第二個引數給模板 template 來直接呈現, 這樣頁面會立即呈現而不是返回一個模板函式。

使用前需要引入underscore-min.js

模板

<!--模板-->
<textarea class="js-tmp" style="display:none;">
    <div class="weui_media_box weui_media_text">
        <a href="<%= url %>" class="" target="_blank">
            <h4 class="weui_media_title"><%= title %></h4>
        </a>
        <p class="weui_media_desc"><%= desc %></p>
    </div>
</textarea>
<!--/模板-->

underscore使用<%= 變數 %>進行表示。

js程式碼
這裡同樣僅展示與上例不一樣的地方:

$.each(data, function(i,el) {
    //可以這樣:
    //var compiled = _.template(htmlTemp);
    //htmlList += compiled(el);
    
    /*或者*/
    htmlList += _.template(htmlTemp)(el);
});

使用方法其實很相似。

  • artTemplate

這個還是比較有名的。

簡介:

artTemplate-3.0 新一代 javascript 模板引擎
https://github.com/aui/artTemplate

template.js (簡潔語法版, 2.7kb)

支援if等語句{{ if admin }}   {{/if}}

template(id, data)
根據 id 渲染模板。內部會根據document.getElementById(id)查詢模板。
如果沒有 data 引數,那麼將返回一渲染函式。


效能卓越,執行速度通常是 Mustache 與 tmpl 的 20 多倍(效能測試)
支援執行時除錯,可精確定位異常模板所在語句(演示)
對 NodeJS Express 友好支援
安全,預設對輸出進行轉義、在沙箱中執行編譯後的程式碼(Node版本可以安全執行使用者上傳的模板)
支援include語句
可在瀏覽器端實現按路徑載入模板(詳情)
支援預編譯,可將模板轉換成為非常精簡的 js 檔案
模板語句簡潔,無需字首引用資料,有簡潔版本與原生語法版本可選
支援所有流行的瀏覽器

artTemplate區分簡潔語法版原生語法版。這裡先演示簡潔語法版

使用前同樣先引入artTemplate.js:

<script src="artTemplate/template.js"></script>

模板

<!--模板-->
<script id="js-tmp" type="text/html">
    <div class="weui_media_box weui_media_text">
        <a href="{{ url }}" class="" target="_blank">
            <h4 class="weui_media_title">{{ title }}</h4>
        </a>
        <p class="weui_media_desc">{{ desc }}</p>
    </div>
</script>
<!--/模板-->

注意這裡模板與前面的示例不一樣了,直接使用一個type="text/html"的script標籤存放模板。artTemplate不支援textarea標籤。

模板裡變數使用{{ 變數 }}佔位。

js程式碼

/本例不再需要手動取模板內容
//var htmlTemp = $("textarea.js-tmp").val();

$.each(data, function(i,el) {
    htmlList += template("js-tmp", el); //注意第一個引數是id
});

artTemplate使用基於document.getElementById(id)的方式直接獲取模板內容。這一點與其它模板有點不同,需要注意。

下面再看看artTemplate原生語法版
需要引入替換成:

<script src="artTemplate/template-native.js"></script>

模板

<!--模板-->
<script id="js-tmp" type="text/html">
    <div class="weui_media_box weui_media_text">
        <a href="<%= url %>" class="" target="_blank">
            <h4 class="weui_media_title"><%= title %></h4>
        </a>
        <p class="weui_media_desc"><%= desc %></p>
    </div>
</script>
<!--/模板-->

原生語法版的artTemplate模板也不一樣,使用<%= 變數 %>的方式表示變數。

js程式碼
無需改動,和上面簡潔語法版是一樣的。

  • BaiduTemplate

宣稱『最簡單好用的JS模板引擎,JS語法學習無成本』 。

簡介:

百度JS模板引擎 baiduTemplate 1.0.6 版 http://tangram.baidu.com/BaiduTemplate/
https://github.com/wangxiao/BaiduTemplate

//方法一:直接傳入data,返回編譯後的HTML片段
var html0 = baidu.template(tpl,data);  

//或直接傳入id即可
var html0 = baidu.template('test1',data);  


支援if等語句<% if(admin) %>   <%}%>

使用前引入:

<script src="BaiduTemplate/baiduTemplate.js"></script>

模板

<!--模板-->
<textarea class="js-tmp" id="js-tmp" style="display:none;">
    <div class="weui_media_box weui_media_text">
        <a href="<%= url %>" class="" target="_blank">
            <h4 class="weui_media_title"><%= title %></h4>
        </a>
        <p class="weui_media_desc"><%= desc %></p>
    </div>
</textarea>
<!--/模板-->

使用<%= 變數 %>的方式表示變數。

js程式碼

var htmlTemp = $("textarea.js-tmp").val();
                        
$.each(data, function(i,el) {
    //htmlList += baidu.template(htmlTemp,el);
    
    //或者通過ID直接得到模板內容:
    htmlList += baidu.template("js-tmp",el);
});

使用很靈活,值得一試。

  • doT

文件是英文的,且不是很詳細。但想想用法也是差不多的。

簡介:

doT.js  https://github.com/olado/doT
olado/doT: The fastest + concise javascript template engine for nodejs and browsers. Partials, custom delimiters and more.

用法類似underscore的_.template

引入doT.min.js:

<script src="dot/doT.min.js"></script>

模板

<!--模板 : 需要加物件字首it-->
<textarea class="js-tmp" style="display:none;">
    <div class="weui_media_box weui_media_text">
        <a href="{{= it.url }}" class="" target="_blank">
            <h4 class="weui_media_title">{{= it.title }}</h4>
        </a>
        <p class="weui_media_desc">{{= it.desc }}</p>
    </div>
</textarea>
<!--/模板-->

和laytpl一樣需要追加字首。使用{{= it.變數 }}表示變數。

js程式碼

$.each(data, function(i,el) {
    //htmlList += _.template(htmlTemp)(el);

    htmlList += doT.template(htmlTemp)(el);
});

沒什麼好說的。這裡加入了_.template的對比,大家看看。

  • Juicer

簡介:

Juicer – 一個Javascript模板引擎的實現和優化 http://juicer.name/
PaulGuo/Juicer: A Light Javascript Templete Engine. https://github.com/PaulGuo/Juicer

當前最新版本: 0.6.14

Juicer 是一個高效、輕量的前端 (Javascript) 模板引擎,使用 Juicer 可以是你的程式碼實現資料和檢視模型的分離(MVC)。除此之外,它還可以在 Node.js 環境中執行。

引入juicer:

<script src="juicer/juicer-min.js"></script>

模板

<!--模板-->
<textarea class="js-tmp" style="display:none;">
    <div class="weui_media_box weui_media_text">
        <a href="${url}" class="" target="_blank">
            <h4 class="weui_media_title">${title}</h4>
        </a>
        <p class="weui_media_desc">${desc}</p>
    </div>
</textarea>
<!--/模板-->

模板表示變數的方式感覺有點彆扭,使用的${變數}

js程式碼

$.each(data, function(i,el) {
    htmlList += juicer(htmlTemp,el);
});