Node 开源模板的选择很多,但推荐像我这样的老人去用 EJS,有 Classic ASP/PHP/JSP 的经验用起 EJS 来的确可以很自然,也就是说,你能够在 <%...%> 块中安排 JavaScript 代码,利用最传统的方式 <%=输出变量%>(另外 <%-输出变量是不会对 & 等符号进行转义的)。安装 EJS 命令如下:

npm install ejs

JS 调用
JS 调用的方法主要有两个:

ejs.compile(str, options); 
// => Function 
 
ejs.render(str, options); 
// => str 

实际上 EJS 可以游离于 Express 独立使用的,例如:

var ejs = require(''), str = require('fs').readFileSync(__dirname   '/list.ejs', 'utf8'); 
 
var ret = ejs.render(str, { 
 names: ['foo', 'bar', 'baz'] 
}); 
 
console.log(ret); 
见 ejs.render(),第一个参数是 模板 的字符串,模板如下。
<% if (names.length) { %> 
 <ul> 
 <% names.forEach(function(name){ %> 
  <li foo='<%= name   "'" %>'><%= name %></li> 
 <% }) %> 
 </ul> 
<% } %> 

names 成了本地变量。

选项参数
第二个参数是数据,一般是一个对象。而这个对象又可以视作为选项,也就是说数据和选择都在同一个对象身上。
如果不想每次都都磁盘,可需要缓存模板,设定 options.filename  即可。例如:

var ejs = require('../') 
 , fs = require('fs') 
 , path = __dirname   '/functions.ejs' 
 , str = fs.readFileSync(path, 'utf8'); 
 
var users = []; 
 
users.push({ name: 'Tobi', age: 2, species: 'ferret' }) 
users.push({ name: 'Loki', age: 2, species: 'ferret' }) 
users.push({ name: 'Jane', age: 6, species: 'ferret' }) 
 
var ret = ejs.render(str, { 
 users: users, 
 filename: path 
}); 
 
console.log(ret); 

inculde 指令
而且,如果要如

<ul>
 <% users.forEach(function(user){ %>
 <% include user/show %>
 <% }) %>
</ul>

般插入公共模板,也就是引入文件,必须要设置 filename 选项才能启动 include 特性,不然 include 无从知晓所在目录。
模板:

<h1>Users</h1> 
 
<% function user(user) { %> 
 <li><strong><%= user.name %></strong> is a <%= user.age %> year old <%= user.species %>.</li> 
<% } %> 
 
<ul> 
 <% users.map(user) %> 
</ul> 

EJS 支持编译模板。经过模板编译后就没有 IO 操作,会非常快,而且可以公用本地变量。下面例子 user/show 忽略 ejs 扩展名:

<ul> 
 <% users.forEach(function(user){ %> 
 <% include user/show %> 
 <% }) %> 
</ul> 

自定义 CLOSE TOKEN
如果打算使用 <h1>{{= title }}</h1> 般非 <%%>标识,也可以自定义的。
var ejs = require('ejs'); 
ejs.open = '{{'; 
ejs.close = '}}'; 
格式化输出也可以哦。
ejs.filters.last = function(obj) { 
 return obj[obj.length - 1]; 
}; 
调用:
<p><%=: users | last %></p> 
EJS 也支持浏览器环境。
<html> 
 <head> 
 <script src="../ejs.js"></script> 
 <script id="users" type="text/template"> 
  <% if (names.length) { %> 
  <ul> 
   <% names.forEach(function(name){ %> 
   <li><%= name %></li> 
   <% }) %> 
  </ul> 
  <% } %> 
 </script> 
 <script> 
  onload = function(){ 
  var users = document.getElementById('users').innerHTML; 
  var names = ['loki', 'tobi', 'jane']; 
  var html = ejs.render(users, { names: names }); 
  document.body.innerHTML = html; 
  } 
 </script> 
 </head> 
 <body> 
 </body> 
</html> 
不知道 EJS 能否输出多层 JSON 对象呢?

对了,有网友爆料说,jQ 大神 John 若干年前写过 20 行的模板,汗颜,与 EJS 相似但短小精悍!

简单实用的js模板引擎
不足 50 行的 js 模板引擎,支持各种 js 语法:

<script id="test_list" type="text/html"> 
<%= 
 for(var i = 0, l = p.list.length; i < l; i  ){ 
  var stu = p.list[i]; 
=%> 
 <tr> 
  <td<%=if(i==0){=%> class="first"<%=}=%>><%==stu.name=%></td> 
  <td><%==stu.age=%></td> 
  <td><%==(stu.address || '')=%></td> 
 <tr> 
 
<%= 
 } 
=%> 
</script> 

 
“<%= xxx =%>”内是 js 逻辑代码,“<%== xxx =%>”内是直接输出的变量,类似 php 的 echo 的作用。“p”是调用下面 build 方法时的 k-v 对象参数,也可以在调用 “new JTemp” 时设置成别的参数名

调用:

$(function(){ 
 var temp = new JTemp('test_list'), 
  html = temp.build( 
   {list:[ 
     {name:'张三', age:13, address:'北京'}, 
    {name:'李四', age:17, address:'天津'}, 
    {name:'王五', age:13} 
   ]}); 
 $('table').html(html); 
}); 

上面的 temp 生成以后,可以多次调用 build 方法,生成 html。以下是模板引擎的代码:

var JTemp = function(){ 
 function Temp(htmlId, p){ 
  p = p || {};//配置信息,大部分情况可以缺省 
  this.htmlId = htmlId; 
  this.fun; 
  this.oName = p.oName || 'p'; 
  this.TEMP_S = p.tempS || '<%='; 
  this.TEMP_E = p.tempE || '=%>'; 
  this.getFun(); 
 } 
 Temp.prototype = { 
  getFun : function(){ 
   var _ = this, 
    str = $('#'   _.htmlId).html(); 
   if(!str) _.err('error: no temp!!'); 
   var str_ = 'var '   _.oName   '=this,f=\'\';', 
    s = str.indexOf(_.TEMP_S), 
    e = -1, 
    p, 
    sl = _.TEMP_S.length, 
    el = _.TEMP_E.length; 
   for(;s >= 0;){ 
    e = str.indexOf(_.TEMP_E); 
    if(e < s) alert(':( ERROR!!'); 
    str_  = 'f =\''   str.substring(0, s)   '\';'; 
    p = _.trim(str.substring(s sl, e)); 
    if(p.indexOf('=') !== 0){//js语句 
     str_  = p; 
    }else{//普通语句 
     str_  = 'f ='   p.substring(1)   ';'; 
    } 
    str = str.substring(e   el); 
    s = str.indexOf(_.TEMP_S); 
   } 
   str_  = 'f =\''   str   '\';'; 
   str_ = str_.replace(/\n/g, '');//处理换行 
   var fs = str_   'return f;'; 
   this.fun = Function(fs); 
  }, 
  build : function(p){ 
   return this.fun.call(p); 
  }, 
  err : function(s){ 
   alert(s); 
  }, 
  trim : function(s){ 
   return s.trim?s.trim():s.replace(/(^\s*)|(\s*$)/g,""); 
  } 
 }; 
 return Temp; 
}(); 

核心是将模板代码转变成了一个拼接字符串的 function,每次拿数据 call 这个 function。

因为主要是给手机(webkit)用的,所以没有考虑字符串拼接的效率问题,如果需要给 IE 使用,最好将字符串拼接方法改为 Array.push() 的形式。

ejs模板布局 layout
1. 如果不愿意使用默认的layout.ejs,可自行指定。例如:

res.render("index",{"title":"test","layout":"main"});
// 或
res.render("index",{"title":"test","layout":"main.ejs"});

2. 如果不愿意使用layout,则可以设置layout为false,例如:

res.render("index",{"layout":false});

3. 如果不想每个请求都单独设置一次。可以使用全局设置:

app.set("view options",{                       
 "layout":false
});

4. ejs 里,默认的闭合标记是 <%  .. %>,我们也可以定义自己的标签。例如:  

app.set("view options",{                     
 "open":"{{",                     
 "close":"}}"
});

5. 局部布局
在web应用中,经常会需要重复显示某个内容,例如:用户评论功能,需要重复显示出每一条用户的评论,这个时候,我们可以通过循环来实现。但是也可以使用【局部模版】( partial)来实现。例如:

首先我们建一个局部的模版 ./views/comment.ejs:

<div class="comment_item">               
 <div class="comment_user"><%=comment.user%></div> 
 <div class="comment_content"><%=comment.content%></div> 
</div>

注意:这里是 comment.xxxx

然后在./views/index.ejs中,通过partial调用comment

this is <%=title%>!               
<br/>               
<%- partial("comment", comments)%>

注意:这里是 partial("comment.ejs", comments); <-- 单词要用复数。

最后是在router中,调用index.ejs。 

 app.get("/",function(req,res){             
 res.render("index",{"title":"test","layout":false,"comments":[             
  {"user":"gainover","content":"test1"},             
  {"user":"zongzi","content":"test2"},             
  {"user":"maomao","content":"test3"}             
 ]});             
});

注意:代码里的 comments 和 index.ejs的 comments变量名称一致,而partial所调用的comment.ejs中,则采用 comment 的单数形式。

在列表显示时,我们通常会遇到的场景是,对第一个元素或者最后一个元素加以特殊显示。在partial中,我们可以通过express内置的变量来判断当前对象是否是第一个元素或者最后一个元素,例如:

 <div class="comment_item<%if(firstInCollection){%> firtitem <%}%>"> 
 <div class="comment_user"><%=comment.user%></div> :        
 <div class="comment_content"><%=comment.content%></div>       
</div>

这样第一条评论的 class 里就会多一个firstitem。

类似的内置变量还有:
(1)firstInCollection 如果是数组的第一个元素,则为true
(2)indexInCollection 当前元素在数组里的索引
(3)lastInCollection 如果是数组的最后一个元素,则为true
(4)collectionLength 数组的长度

最后是partial调用模版时的路径查找问题:

(1)partial("edit") 会查找同目录下的edit.ejs文件。
(2)partial("../message") 会查找上一级目录的message.ejs文件。
(3)partial("users") 会查找 users.ejs文件,如果不存在users.ejs, 则会查找 /users/index.ejs文件。

(4)<%= users %> 会对内容进行转义,想不转义,可以用 <%- users %>

Node.js的Web模板引擎ejs的入门使用教程的更多相关文章

  1. CentOS 8.2服务器上安装最新版Node.js的方法

    这篇文章主要介绍了CentOS 8.2服务器上安装最新版Node.js的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  2. node.js三个步骤实现一个服务器及Express包使用

    这篇文章主要介绍了node.js三个步骤实现一个服务器及Express包使用,文章通过新建一个文件展开全文内容,具有一定的参考价值,需要的小伙伴可以参考一下

  3. Node.js调试技术总结分享

    Node.js是一个可以快速构建网络服务及应用的平台。该平台的构建是基于Chrome's JavaScript runtime,也就是说,实际上它是对Google V8引擎(应用于Google Chrome浏览器)进行了封装。 今天介绍Node.js调式目前有几种技术,需要的朋友可以参考下。

  4. node.js实现http服务器与浏览器之间的内容缓存操作示例

    这篇文章主要介绍了node.js实现http服务器与浏览器之间的内容缓存操作,结合实例形式分析了node.js http服务器与浏览器之间的内容缓存原理与具体实现技巧,需要的朋友可以参考下

  5. 教你如何使用node.js制作代理服务器

    本文介绍了如何使用node.js制作代理服务器,图文并茂,十分的详细,代码很简洁易懂,这里推荐给大家。

  6. node.js中的fs.openSync方法使用说明

    这篇文章主要介绍了node.js中的fs.openSync方法使用说明,本文介绍了fs.openSync方法说明、语法、接收参数、使用实例和实现源码,需要的朋友可以参考下

  7. Node.js+ELK日志规范的实现

    这篇文章主要介绍了Node.js+ELK日志规范的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  8. node.js爬虫框架node-crawler初体验

    这篇文章主要介绍了node.js爬虫框架node-crawler的相关资料,帮助大家利用node.js进行爬虫,感兴趣的朋友可以了解下

  9. node.js中的fs.existsSync方法使用说明

    这篇文章主要介绍了node.js中的fs.existsSync方法使用说明,本文介绍了fs.existsSync方法说明、语法、接收参数、使用实例和实现源码,需要的朋友可以参考下

  10. 说说如何利用 Node.js 代理解决跨域问题

    这篇文章主要介绍了Node.js代理解决跨域问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

随机推荐

  1. Error: Cannot find module ‘node:util‘问题解决

    控制台 安装 Vue-Cli 最后一步出现 Error: Cannot find module 'node:util' 问题解决方案1.问题C:\Windows\System32>cnpm install -g @vue/cli@4.0.3internal/modules/cjs/loader.js:638 throw err; &nbs

  2. yarn的安装和使用(全网最详细)

    一、yarn的简介:Yarn是facebook发布的一款取代npm的包管理工具。二、yarn的特点:速度超快。Yarn 缓存了每个下载过的包,所以再次使用时无需重复下载。 同时利用并行下载以最大化资源利用率,因此安装速度更快。超级安全。在执行代码之前,Yarn 会通过算法校验每个安装包的完整性。超级可靠。使用详细、简洁的锁文件格式和明确的安装算法,Yarn 能够保证在不同系统上无差异的工作。三、y

  3. 前端环境 本机可切换node多版本 问题源头是node使用的高版本

    前言投降投降 重头再来 重装环境 也就分分钟的事 偏要折腾 这下好了1天了 还没折腾出来问题的源头是node 使用的高版本 方案那就用 本机可切换多版本最终问题是因为nodejs的版本太高,导致的node-sass不兼容问题,我的node是v16.14.0的版本,项目中用了"node-sass": "^4.7.2"版本,无法匹配当前的node版本根据文章的提

  4. nodejs模块学习之connect解析

    这篇文章主要介绍了nodejs模块学习之connect解析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. nodejs npm package.json中文文档

    这篇文章主要介绍了nodejs npm package.json中文文档,本文档中描述的很多行为都受npm-config(7)的影响,需要的朋友可以参考下

  6. 详解koa2学习中使用 async 、await、promise解决异步的问题

    这篇文章主要介绍了详解koa2学习中使用 async 、await、promise解决异步的问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. Node.js编写爬虫的基本思路及抓取百度图片的实例分享

    这篇文章主要介绍了Node.js编写爬虫的基本思路及抓取百度图片的实例分享,其中作者提到了需要特别注意GBK转码的转码问题,需要的朋友可以参考下

  8. CentOS 8.2服务器上安装最新版Node.js的方法

    这篇文章主要介绍了CentOS 8.2服务器上安装最新版Node.js的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  9. node.js三个步骤实现一个服务器及Express包使用

    这篇文章主要介绍了node.js三个步骤实现一个服务器及Express包使用,文章通过新建一个文件展开全文内容,具有一定的参考价值,需要的小伙伴可以参考一下

  10. node下使用UglifyJS压缩合并JS文件的方法

    下面小编就为大家分享一篇node下使用UglifyJS压缩合并JS文件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

返回
顶部