不会的要多查多问,不然不会的永远不会,哪怕你离会就差了那么一点点
第一页 1 最后页 [ 显示模式: 摘要 | 列表 ]

几个模板引擎的对比

[不指定 2016/09/05 23:56 | by 刘新修 ]

渲染html到页面中,在koa中可以这么干:

JavaScript代码
  1. app.get('/',function*(){  
  2.     this.body = "<p>'+title+'</p>";  
  3. })  

但问题很大,模板混入到js逻辑了,非常不利于维护,基于 mvc 模式,我们需要将html模板抽离到 view 中方便维护,这时候我们就需要一款模板渲染引擎。

为什么选择xtemplate

适用于 koa 的模板引擎选择非常多,比如 jadeejsnunjucksxtemplate 等。

为什么选择 xtemplate 呢?

上手难度

jade 无疑是最独特,上手难度最高,特别是将 html 转成 jade 风格的代码,需要一些成本和适应,特别是空格敏感,经常引起模块渲染报错:

JavaScript代码
  1. body  
  2.     h1 Jade - node template engine  
  3.     #container.col  
  4.       if youAreUsingJade  
  5.         p You are amazing  
  6.       else  
  7.         p Get on it!  

但 jade 在 express 中拥有广泛的群众基础,所以从 express 转到 koa,jade 是个不错的选择,但我一直认为 jade 不是最佳的模板选择。

ejs、nunjucks、xtemplate 的上手难度差不多,但ejs的扩展写法有些诡异,特别是 filter 的写法:

JavaScript代码
  1. <p><%=: users | first | capitalize %></p>  

xtemplate 相对于 nunjucks 的优势是,模板的逻辑写法体验更接近js(ejs的逻辑表达也很接近js),上手更为简单,来看下同样一个 if 判断的写法差异。

xtemplate:

JavaScript代码
  1. {{#if(variable===0)}}  
  2.   It is true      
  3. {{/if}}  

nunjucks:

JavaScript代码
  1. {% if variable == 0 %}  
  2.   It is true  
  3. {% endif %}  

所以上手难度:xtemplate < nunjucks < ejs < jade 。

功能的强大度

四款模板引擎必备几样功能都具备:变量、逻辑表达式、循环、layout、include、宏、扩展等。

nunjucks 无疑是功能最全面的模板引擎,xtemplate 拥有 nunjucks 大部分的特性,除了filter,但 xtemplate 拥有非常强悍的拓展性:

JavaScript代码
  1. xtpl.addCommand('money',function(scope, option){  
  2.     var money = option.params[0];  
  3.     if(typeof money !== 'number') return '';  
  4.     //金额除以100(接口返回的金额都是以分为单位,转成元)  
  5.     var s = Number(money)/100;  
  6.     return s;  
  7. })  

模板中使用:

JavaScript代码
  1. {{money(10000)}}  

nunjucks 与 xtemplate 都拥有实用的宏定义功能:

JavaScript代码
  1. {{#macro("test","param", default=1)}}  
  2.     param is {{param}} {{default}}  
  3. {{/macro}}  

模板中使用:

JavaScript代码
  1. {{macro("test","2")}}  

输出内容:

JavaScript代码
  1. param is 2 1  

jade 中的 Mixins,ejs 中的 function 也可以实现类似的抽取公用html代码块的目的 。

如果真要分个高下:nunjucks > xtemplate > jade > ejs 。

是否支持前后端混用

jade 直接淘汰,相信在前端js领域一般不会选择 jade 来渲染。

nunjucks 也使用的比较少(ejs其实也少),更多人会选择使用 handlebars 。

xtemplate 目前在阿里的系统中前后端混用中已经得到论证,节约了模板前后端转换的时间。

事实上是否支持前后端混用不是决定性因素,特别是在 angularjs 盛行的年代。

性能考量

它们都很快,其实性能都不是问题,真要较真的话,xtemplate 会更优秀些,可以看 xtemplate benchmark

个人觉得性能不是决定性因素。

基于上述几点考虑,推荐使用 xtemplate 。

Tags: ,

ArtTemplate_List 实例

[不指定 2016/08/02 16:56 | by 刘新修 ]

ArtTemplate_List 实例1

XML/HTML代码
  1. <!DOCTYPE HTML>  
  2. <html>  
  3. <head>  
  4. <meta charset="UTF-8">  
  5. <title>basic-demo</title>  
  6. <script src="../dist/template.js"></script>  
  7. </head>  
  8.   
  9. <body>  
  10. <div id="content"></div>  
  11. <script id="test" type="text/html">  
  12. {{if isAdmin}}  
  13.   
  14. <h1>{{title}}</h1>  
  15. <ul>  
  16.     {{each list as value i}}  
  17.         <li>索引 {{i + 1}} :{{value}}</li>  
  18.     {{/each}}  
  19. </ul>  
  20.   
  21. {{/if}}  
  22. </script>  
  23.   
  24. <script>  
  25. var data = {  
  26.     title: '基本例子',  
  27.     isAdmin: true,  
  28.     list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他']  
  29. };  
  30. var html = template('test', data);  
  31. document.getElementById('content').innerHTML = html;  
  32. </script>  
  33. </body>  
  34. </html  

ArtTemplate_List 实例2

XML/HTML代码
  1. <!DOCTYPE HTML>  
  2. <html>  
  3. <head>  
  4. <meta charset="UTF-8">  
  5. <title>compile-demo</title>  
  6. <script src="../dist/template.js"></script>  
  7. </head>  
  8.   
  9. <body>  
  10. <h1>在javascript中存放模板</h1>  
  11. <div id="content"></div>  
  12. <script>  
  13. var source = '<ul>'  
  14. +    '{{each list as value i}}'  
  15. +        '<li>索引 {{i + 1}} :{{value}}</li>'  
  16. +    '{{/each}}'  
  17. + '</ul>';  
  18.   
  19. var render = template.compile(source);  
  20. var html = render({  
  21.     list: ['摄影', '电影', '民谣', '旅行', '吉他']  
  22. });  
  23.   
  24. document.getElementById('content').innerHTML = html;  
  25. </script>  
  26. </body>  
  27. </html>  
XML/HTML代码
  1. <!DOCTYPE HTML>  
  2. <html>  
  3. <head>  
  4. <meta charset="UTF-8">  
  5. <title>basic-demo</title>  
  6. <script src="../dist/template.js"></script>  
  7. </head>  
  8.   
  9. <body>  
  10. <h1>在javascript中存放模板</h1>    
  11. <div id="content"></div>    
  12. <script>  
  13. /***** 小模版 *****/  
  14. var source=''  
  15. +'<ul>'    
  16. +    '{{each list as value i}}'    
  17. +        '<li>索引 {{i+1}} :{{value}}</li>'  
  18. +    '{{/each}}'    
  19. +'</ul>';  
  20.   
  21. /***** 定义变关联逻辑代码片段(小模版) *****/    
  22. var connectJs=template.compile(source);  
  23.   
  24. /***** 最终的数据源等于==逻辑代码关联数据 *****/  
  25. var htmlData=connectJs({  
  26.     list: ['摄影', '电影', '民谣', '旅行', '吉他']    
  27. });    
  28.   
  29. /***** 把最终处理后的数据源插入到页面 *****/    
  30. document.getElementById('content').innerHTML=htmlData;    
  31. </script>  
  32. </body>  
  33. </html>  

实例访问地址:http://code.liuxinxiu.com/jstpl/artTemplate/demo/best.html

include嵌入子模板:

XML/HTML代码
  1. <!DOCTYPE HTML>  
  2. <html>  
  3. <head>  
  4. <meta charset="UTF-8">  
  5. <title>include-demo</title>  
  6. <script src="../dist/template.js"></script>  
  7. </head>  
  8.   
  9. <body>  
  10. <div id="content"></div>  
  11. <script id="test" type="text/html">  
  12. <h1>{{title}}</h1>  
  13. {{include 'list'}}  
  14. </script>  
  15. <script id="list" type="text/html">  
  16. <ul>  
  17.     {{each list as value i}}  
  18.         <li>索引 {{i + 1}} :{{value}}</li>  
  19.     {{/each}}  
  20. </ul>  
  21. </script>  
  22.   
  23. <script>  
  24. var data = {  
  25.     title: '嵌入子模板',  
  26.     list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他']  
  27. };  
  28. var html = template('test', data);  
  29. document.getElementById('content').innerHTML = html;  
  30. </script>  
  31. </body>  
  32. </html>  

理解部分(使用普通for循环加声明语法,进行数组遍历)1:

XML/HTML代码
  1. <!DOCTYPE html>  
  2. <html lang="en">  
  3. <head>  
  4.     <meta charset="UTF-8">  
  5.     <title>AtrTemplate</title>  
  6. </head>  
  7. <body>  
  8.     <div id="content"></div>  
  9.   
  10.     <script src="js/template-native.js"></script>  
  11.     <script id="test" type="text/html">  
  12.           
  13.         <%for( i = 0; i < content.length; i++) {%>  
  14.         <h1><%=content[i].title%></h1>  
  15.         <p>条目内容 : <%=content[i].list%></p>  
  16.         <%}%>  
  17.       
  18.     // 等同于普通的for循环,在普通的for循环上给每一行语法声明加上<% xx %>  
  19.     // 等同于普通的for循环,在普通的for循环上取值部分加上类似jsp的变量声明 <%= xx %>  
  20.         //for(i=0;i<content.length;i++){  
  21.         //  <h1><%=content[i].title%></h1>  
  22.         //  <p>条目内容 : <%=content[i].list%></p>  
  23.         //}  
  24.           
  25.     </script>  
  26.   
  27.     <script>  
  28.     /***** 自造数据,content为数组List便于测试循环 *****/  
  29.         var data={  
  30.             content:[  
  31.                 {  
  32.                     title: "artTemplate",  
  33.                     list: "新一代 javascript 模板引擎",  
  34.                 },  
  35.                 {  
  36.                     title: "特性",  
  37.                     list: "性能卓越,执行速度快"  
  38.                 }  
  39.             ]  
  40.         };  
  41.     /***** 用template映射数据到逻辑代码区域|也可以理解称给逻辑代码片段绑定数据源 *****/  
  42.         var html=template('test',data);  
  43.     /***** 选择页面Dom元素,插入处理后的数据 *****/  
  44.         document.getElementById("content").innerHTML=html;  
  45.    </script>  
  46. </body>  
  47. </html>  

理解部分(使用普通for循环加声明语法,进行双层嵌套数组遍历)2:

XML/HTML代码
  1. <!DOCTYPE html>  
  2. <html lang="en">  
  3. <head>  
  4.     <meta charset="UTF-8">  
  5.    <title>AtrTemplate -- 简介</title>  
  6. </head>  
  7. <body>  
  8.     <div id="content"></div>  
  9.   
  10.     <script src="js/template-native.js"></script>  
  11.     <script id="listtemp">  
  12.   
  13.     </script>  
  14.     <script id="test" type="text/html">  
  15.         //循环嵌套,循环数组里的数组  
  16.         <%for(i=0;i<content.length;i++){%>  
  17.         <h1><%=content[i].title%></h1>  
  18.         <ul>  
  19.             <%for(j=0;j<content[i].list.length;j++){%>  
  20.                 <li><%=content[i].list[j]%></li>  
  21.             <%}%>  
  22.         </ul>  
  23.         <%}%>  
  24.           
  25.     </script>    
  26.     <script>
  27.         var data={  
  28.             content:[  
  29.                 {  
  30.                     title: "artTemplate",  
  31.                     list:["新一代 javascript 模板引擎"]  
  32.                 },  
  33.                 {  
  34.                     title: "特性",  
  35.                     list: [  
  36.                             "性能卓越,执行速度通常是 Mustache 与 tmpl 的 20 多倍",  
  37.                             "支持运行时调试,可精确定位异常模板所在语句",  
  38.                             " 对 NodeJS Express 友好支持",  
  39.                             "安全,默认对输出进行转义、在沙箱中运行编译后的代码(Node版本可以安全执行用户上传的模板)",  
  40.                             " 支持include语句",  
  41.                             "可在浏览器端实现按路径加载模板",  
  42.                             "支持预编译,可将模板转换成为非常精简的 js 文件",  
  43.                             "模板语句简洁,无需前缀引用数据,有简洁版本与原生语法版本可选",  
  44.                             "支持所有流行的浏览器"  
  45.                         ]  
  46.                 }  
  47.             ]  
  48.         };
  49. /***** 用template映射数据到逻辑代码区域|也可以理解称给逻辑代码片段绑定数据源 *****/
  50.         var html=template('test',data);
  51.  
  52. /***** 选择页面Dom元素,插入处理后的数据 *****/
  53.         document.getElementById("content").innerHTML=html;  
  54.     </script>  
  55. </body>  
  56. </html>  

 

Tags:
第一页 1 最后页 [ 显示模式: 摘要 | 列表 ]