腾讯art-template4,即vue后又获一利器
腾讯art-template4,即vue后又获一利器art-template是一个简约、超快的模板引擎,官方给出的优点及特性是:1.拥有接近JavaScript 渲染极限的的性能2.调试友好:语法、运行时错误日志精确到模板所在行;支持在模板文件上打断点(Webpack Loader)3.支持Express、Koa、Webpack4.支持模板继承与子模板5.浏览器
腾讯art-template4,即vue后又获一利器
art-template是一个简约、超快的模板引擎,官方给出的优点及特性是:
1.拥有接近 JavaScript 渲染极限的的性能
2.调试友好:语法、运行时错误日志精确到模板所在行;支持在模板文件上打断点(Webpack Loader)
3.支持 Express、Koa、Webpack
4.支持模板继承与子模板
5.浏览器版本仅 6KB 大小
其中第2点看出来不错哦,支付打断点,其它几个优点见仁见智。
首先了解一下框架工作流程,大致可以分为两步:编辑模板和渲染模板。
编辑模板就是将需要动态生成的DOM抽象成为模板,渲染则是利用渲染函数,把后端返回的数据 填入模板中相应的位置上,生成最终的html串并且回填到html页面的指定位置中。
下面开始学习这旅吧。
1.先去网络或github上去下载art-template.js文件,然后在html或jsp里引入文件即可以使用
<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}}
只将数据放到胡子,其它标签安jsp或html语法写
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.模拟for或foreach逻辑。如上面的例子:
<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-template的2种渲染方式。
第一种直接提供模板名和数据源渲染,再将渲染后的模板页面添加到jsp里某个dom元素里。使用template(“filename”,content)
Filename:模板名,如上面script脚本id,或者单独抽出来的子模板路径,
Content:如果提供的是object,一般当做提供的是json格式数据,那么template方法会渲染模板将以string形势返回渲染后的结果,最张将返回的string添加到dom元素上。
如果 content为string,则编译模板并返回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>
结果如下:
模板id为test使用Includ函数包裹了一个模板id为list的模板。虽然显示出来了,但这里有个坑。所以模板都必需写在同一个html或jsp里,不同模板可以写在不 同的<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 新特性一览教程
更多推荐
所有评论(0)