腾讯art-template4,即vue后又获一利器

来源:互联网 发布:nginx module 编辑:程序博客网 时间:2024/05/16 08:39

腾讯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 * @seehttp://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-minifierhtmlMinifierOptions: {    collapseWhitespace: true,    minifyCSS: true,    minifyJS: true,    // 运行时自动合并:rules.map(rule => rule.test)    ignoreCustomFragments: []},// 错误事件。仅在 bail 为 false 时生效onerror: onerror,// 模板文件加载器loader: loader,// 缓存中心适配器(依赖 filename 字段)caches: caches,// 模板根目录。如果 filename 字段不是本地路径,则在 root 查找模板root: '/',// 默认后缀名。如果没有后缀名,则会自动添加 extnameextname: '.art',// 忽略的变量。被模板编译器忽略的模板变量列表ignore: [],// 导入的模板变量imports: runtime

至于有多少是有用的,只能见仁见智

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

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

art-template@4 新特性一览

Github源码

教程


原创粉丝点击