騰訊art-template4,即vue後又獲一利器

陳袁發表於2017-08-09

騰訊art-template4,即vue後又獲一利器

art-template是一個簡約、超快的模板引擎,官方給出的優點及特性是:

1.擁有接近 JavaScript 渲染極限的的效能

2.除錯友好:語法、執行時錯誤日誌精確到模板所在行;支援在模板檔案上打斷點(Webpack Loader

3.支援 ExpressKoaWebpack

4.支援模板繼承與子模板

5.瀏覽器版本僅 6KB 大小

其中第2點看出來不錯哦,支付打斷點,其它幾個優點見仁見智。

首先了解一下框架工作流程,大致可以分為兩步:編輯模板和渲染模板。

編輯模板就是將需要動態生成的DOM抽象成為模板,渲染則是利用渲染函式,把後端返回的資料 填入模板中相應的位置上,生成最終的html串並且回填到html頁面的指定位置中。

 

下面開始學習這旅吧。

1.先去網路或github上去下載art-template.js檔案,然後在htmljsp裡引入檔案即可以使用

<script src="https://github.com/aui/art-template/tree/master/lib/template-web.js"></script>


2.學習一個框架,從3點開始下手

第一:資料怎麼展示

第二:資料怎麼提供

第三:資料怎麼生效。

2.1 第一:資料怎麼展示:

ArtTemplate提供2種語法

1.標準語法或叫做極簡語法,使用的是雙大括號或者叫“鬍子”,推薦使用,看起來簡潔

{{if data}}
  <h2>{{data.name}}</h2>
{{/if}}


只將資料放到鬍子,其它標籤安jsphtml語法寫

2.原始語法,<%%>

<% if (data) { %>

  <h2><%= data.name %></h2>

<% } %>


使用jsp的語法,我們知道”<%%>”裡是可以寫java程式碼的,可以定義區域性變數和java程式碼語句。把資料和邏輯那塊放到<%%>裡寫,其它按正常的邏輯寫,類似寫jsp。缺點是看起來不整潔,特別是頁面複雜的,優點是擁有強大的邏輯表達能力

 

3.雙大括號或鬍子裡可以使用的邏輯符包括.”[]”,”三目運算子”,”||&”,”邏輯運算子”。如下:

{{value}}

{{data.key}}

{{data['key']}}

{{a ? b : c}}

{{a || b}}

{{a + b}}

例子如下:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>basic-demo</title>
<script src="../lib/template-web.js"></script>
</head>

<body>
<div id="content"></div>
<script id="test" type="text/html">
<h1>{{name}}性別是{{sex==1?'男':'女'}}</h1>

<ul>
    {{each list value i}}
        <li>第{{i + 1}}門課 :{{value}}</li>
    {{/each}}
</ul>
<h1>其中數學和英語總分:{{math+english}}</h1>
</script>

<script>
var data = {
	name:"小明",
	sex:1,
	math:90,
	english:73,
	list: ['文藝','數學','英語', '部落格', '攝影', '電影', '民謠', '旅行', '吉他']
};
var html = template('test', data);
document.getElementById('content').innerHTML = html;
</script>
</body>
</html>





渲染出來的結果:

1).紅色部分是我們特別關注的地方,強調一點,這裡的模組指的是用

<script type="text/html">

XXXX程式碼

</script>


包裹的部分。鬍子和標籤都在裡面寫,指令碼視做一個模組。

2).鬍子裡可以使用指定的操作符,如邏輯判斷有運算子,如果不足夠,可以使用原始語法,那裡邏輯運算比較全面。

3).讓渲染出來的元素在頁面上生效。

var html = template('test', data);

document.getElementById('content').innerHTML = html;



4.條件判斷

{{if value}} ... {{/if}}

{{if v1}} ... {{else if v2}} ... {{/if}}

所以取資料和邏輯判斷都在鬍子裡。例子:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>basic-demo</title>
<script src="../lib/template-web.js"></script>
<script src="../lib/jquery.2.1.1.min.js"></script>
</head>

<body>
<div id="content"></div>
<script id="testP" type="text/html">
<h1>{{name}}性別是{{sex==1?'男':'女'}}</h1>
{{if math > 90}}
<2>數學成績上等</h2>
{{else if math >70}}
<h2>數學成績中等</h2>
{{else if math > 60}}
<h2>數學成績及格</h2>
{{/if}}
<ul>
    {{each list value i}}
        <li>第{{i + 1}}門課 :{{value}}</li>
    {{/each}}
</ul>
<h1>其中數學和英語總分:{{math+english}}</h1>
</script>

<script>
var data = {
	name:"小明",
	sex:1,
	math:90,
	english:73,
	list: ['文藝','數學','英語', '部落格', '攝影', '電影', '民謠', '旅行', '吉他']
};
var html = template('testP', data);
document.getElementById('content').innerHTML = html;
</script>
</body>
</html>



結果如下:


看紅色部分,以{{if value}}開頭,以{{/if}}結尾,中間可以有else if。可以做到java

if(value){

}else if(value){

}else if(value){

}



5.模擬forforeach邏輯。如上面的例子:

<ul>
    {{each list value i}}
        <li>第{{i + 1}}門課 :{{value}}</li>
    {{/each}}
</ul>



6.設定變數:{{set temp = value}}

例如:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>basic-demo</title>
<script src="../lib/template-web.js"></script>
<script src="../lib/jquery.2.1.1.min.js"></script>
</head>

<body>
<div id="content"></div>
<script id="testP" type="text/html">
{{set nb=math+english}}
<h2>數字的別名nb值:{{nb}}</h2>
<h1>{{name}}性別是{{sex==1?'男':'女'}}</h1>
{{if math > 90}}
<2>數學成績上等</h2>
{{else if math >70}}
<h2>數學成績中等</h2>
{{else if math > 60}}
<h2>數學成績及格</h2>
{{/if}}
<ul>
    {{each list value i}}
        <li>第{{i + 1}}門課 :{{value}}</li>
    {{/each}}
</ul>
<h1>其中數學和英語總分:{{math+english}}</h1>
</script>

<script>
var data = {
	name:"小明",
	sex:1,
	math:90,
	english:73,
	list: ['文藝','數學','英語', '部落格', '攝影', '電影', '民謠', '旅行', '吉他']
};
var html = template('testP', data);
document.getElementById('content').innerHTML = html;
</script>
</body>
</html>




7.過濾器

template.defaults.imports.dateFormat = function(date, format){/*[code..]*/};

template.defaults.imports.timestamp = function(value){return value * 1000};

使用{{value|filter}}

使用類似管道符來傳遞資料,資料會傳遞到定義的過濾器函式filter

<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>helper-demo</title>
<script src="../../lib/template-web.js"></script>
</head>

<body>
<h1>自定義過濾器</h1>
<div id="content"></div>
<script id="test" type="text/html">
<h2>過濾的第一種使用方法:{{time | dateFormat:'yyyy年 MM月 dd日 hh:mm:ss'}}</h2>
<h2>過濾的第二種使用方法:{{$imports.dateFormat(1408536771253,'yyyy年 MM月 dd日 hh:mm:ss')}}</h2>
<h2>特例:{{$imports.test(1408536771253)}}</h2>
</script>

<script>


/**
 * 對日期進行格式化,
 * @param date 要格式化的日期
 * @param format 進行格式化的模式字串
 *     支援的模式字母有:
 *     y:年,
 *     M:年中的月份(1-12),
 *     d:月份中的天(1-31),
 *     h:小時(0-23),
 *     m:分(0-59),
 *     s:秒(0-59),
 *     S:毫秒(0-999),
 *     q:季度(1-4)
 * @return String
 * @author yanis.wang
 * @see	http://yaniswang.com/frontend/2013/02/16/dateformat-performance/
 */
 function test(value){
	return value;
 }
 
template.defaults.imports.dateFormat =  function (date, format) {

    if (typeof date === "string") {
        var mts = date.match(/(\/Date\((\d+)\)\/)/);
        if (mts && mts.length >= 3) {
            date = parseInt(mts[2]);
        }
    }
    date = new Date(date);
    if (!date || date.toUTCString() == "Invalid Date") {
        return "";
    }

    var map = {
        "M": date.getMonth() + 1, //月份
        "d": date.getDate(), //日
        "h": date.getHours(), //小時
        "m": date.getMinutes(), //分
        "s": date.getSeconds(), //秒
        "q": Math.floor((date.getMonth() + 3) / 3), //季度
        "S": date.getMilliseconds() //毫秒
    };


    format = format.replace(/([yMdhmsqS])+/g, function(all, t){
        var v = map[t];
        if(v !== undefined){
            if(all.length > 1){
                v = '0' + v;
                v = v.substr(v.length-2);
            }
            return v;
        }
        else if(t === 'y'){
            return (date.getFullYear() + '').substr(4 - all.length);
        }
        return all;
    });
    return format;
};

// --------

var data = {
	time: 1408536771253,
};
var html = template('test', data);
document.getElementById('content').innerHTML = html;
</script>
</body>
</html>



結果如下


第一種方式是直接使用方式,通過管道符將資料拿到過濾器裡,第二種方式是函式方式,我們知道,模板通過 $imports可以訪問到模板外部的全域性變數與匯入的變數,我們可以使用$import直接方式通過template.defaults.imports匯入的函式或變數,也可以訪問全域性的函式或變數,注意是全域性的,所以通過$imports可以直接呼叫方法或變數,所以,有第3個例子,通過$imports模板變數訪問了沒匯入但是是全域性的test函式。


art-template.js提供瞭如下幾種內建變數:

1.$data 傳入模板的資料,如上資料可以$data.math訪問到數學分數是多少

2.$imports外部匯入的變數以及全域性變數,(重要,重點,重量,重要的事說3遍,還不帶重的)

3.print 字串輸出函式,後面可根隨機個值,然後將拼接的字串列印出來,比如如上資料:<h2>print函式:print name "的數學是"  math ",英文是" english  ",總分是" {{math + english}}</h2>

結果如下:



4.include子模板載入函式

5.extend模板繼承模板匯入函式

6.block 模板塊宣告函式


第二:資料怎麼提供

我們知道js裡提供資料常用json格式,資料怎麼提供的問題涉及到art-template2種渲染方式。

第一種直接提供模板名和資料來源渲染,再將渲染後的模板頁面新增到jsp裡某個dom元素裡。使用template(“filename”,content)

Filename:模板名,如上面script指令碼id,或者單獨抽出來的子模板路徑,

Content:如果提供的是object,一般當做提供的是json格式資料,那麼template方法會渲染模板將以string形勢返回渲染後的結果,最張將返回的string新增到dom元素上。

如果 contentstring,則編譯模板並返回function

一般使用方式是var html = template('testP', data);然後將返回的字串html插入到dom元素上document.getElementById('content').innerHTML = html;

 

第二種。以字串形勢提供模板,呼叫 compile或者render編譯模板,然後將資料提供給模板。注意以字串形勢提供的模板嚴格來講並不是”模板“,必需經過編譯才行。例如:

var source = '<ul>'
+    '{{each list value i}}'
+        '<li>索引 {{i + 1}} :{{value}}</li>'
+    '{{/each}}'
+ '</ul>';
var data = {
    list: ['攝影', '電影', '民謠', '旅行', '吉他']
}
var render = template.compile(source);
var html = render(data);



結果:

compile(source, options)編譯模板並返回一個渲染函式。先編譯再提供資料

或者編譯和提供資料放一起

var render = template.render(source,data);

document.getElementById('content').innerHTML = render;

結果同上。

 

所以:

template(filename, content)

compile(source, options)

render(source, data)

即是提供資料和讓資料怎麼生效的三種方式。這也解釋了第三個問題資料怎麼生效

第三:資料怎麼生效

見第二解答。


高階用法include函式,

{{include '模板id'}}

{{include '模板id' data}}

data 數預設值為$data,也可賦值,指定資料來源

例子:

<body>
<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 value i}}
        <li>索引 {{i + 1}} :{{value}}</li>
    {{/each}}
</ul>
</script>

<script>


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



結果如下:



模板idtest使用Includ函式包裹了一個模板idlist的模板。雖然顯示出來了,但這裡有個坑。所以模板都必需寫在同一個htmljsp裡,不同模板可以寫在不 同的<script id="xxx" type="text/html">,用id區別。換名話說include只能包裹同一頁面的模板,如果模板存放在其它目錄中則include無效。如果想要獨立出模板放在單獨檔案裡,需要使用企鵝開發的另一個框架TmodJS,它和art-template都是一家公司開發的TmodJS框架依賴於art-template框架的一款模板預編譯器,感覺興趣的同學可以自行百度

 

到這裡我們基本上學會了art-template.js。如果說還有什麼要學習的,估計就是框架的配置了。

配置

1.框架提供了.defaults屬性,裡面可以設定很多框架的預設屬性。上面我們學習到的imports就是.defaults裡的屬性template.defaults.imports.XXX變數=XXX值。

它也提供了其它一些預設引數設定。

// 模板名
filename: null,
// 模板語法規則列表
rules: [nativeRule, artRule],
// 是否開啟對模板輸出語句自動編碼功能。為 false 則關閉編碼輸出功能
// escape 可以防範 XSS 攻擊
escape: true,
// 啟動模板引擎除錯模式。如果為 true: {cache:false, minimize:false, compileDebug:true}
debug: detectNode ? process.env.NODE_ENV !== 'production' : false,
// bail 如果為 true,編譯錯誤與執行時錯誤都會丟擲異常
bail: true,
// 是否開啟快取
cache: true,
// 是否開啟壓縮。它會執行 htmlMinifier,將頁面 HTML、CSS、CSS 進行壓縮輸出
// 如果模板包含沒有閉合的 HTML 標籤,請不要開啟 minimize,否則可能被 htmlMinifier 修復或過濾
minimize: true,
// 是否編譯除錯版
compileDebug: false,
// 模板路徑轉換器
resolveFilename: resolveFilename,
// 子模板編譯介面卡
include: include,
// HTML 壓縮器。僅在 NodeJS 環境下有效
htmlMinifier: htmlMinifier,
// HTML 壓縮器配置。參見 https://github.com/kangax/html-minifier
htmlMinifierOptions: {
    collapseWhitespace: true,
    minifyCSS: true,
    minifyJS: true,
    // 執行時自動合併:rules.map(rule => rule.test)
    ignoreCustomFragments: []
},
// 錯誤事件。僅在 bail 為 false 時生效
onerror: onerror,
// 模板檔案載入器
loader: loader,
// 快取中心介面卡(依賴 filename 欄位)
caches: caches,
// 模板根目錄。如果 filename 欄位不是本地路徑,則在 root 查詢模板
root: '/',
// 預設字尾名。如果沒有字尾名,則會自動新增 extname
extname: '.art',
// 忽略的變數。被模板編譯器忽略的模板變數列表
ignore: [],
// 匯入的模板變數
imports: runtime



至於有多少是有用的,只能見仁見智

2.除了直接使用.defaults外,框架還提供了config(name,value)函式,按上面提供的配置屬性填值即可。

想要了解最多建議去gitHub上看。

art-template@4 新特性一覽

Github原始碼

教程


相關文章