Web模板引擎
-
- 1、ejs模块
- 2、pug模块
-
- 2.1、基本语法
-
- 2.1.1、缩进
- 2.1.2、注释
- 2.1.3、属性
- 2.1.4、包含
- 2.1.5、定义变量
- 2.1.6、条件结构
- 2.1.7、循环结构
- 2.1.8、minix
- [2.1.9、 定义JavaScript代码](#2.1.9、 定义JavaScript代码)
- 2.1.10、继承
- 2.2、pug的渲染方法
- 2.3、渲染示例
- 2.4、pug的数据传递
1、ejs模块
ejs是embedded JavaScript的缩写,翻译为嵌入式Javascript。ejs模块是一种高效的JavaScript模板引擎,它可以通过解析JavaScript代码生成HTML页面,并且直接支持在标签内书写简洁的JavaScript代码,以让JavaScript输出所需的HTML,使得代码后期维护更轻松。
使用ejs模块之前,首先需要使用npm命令进行下载和安装,命令如下:
js
npm install ejs
1.1、ejs的渲染方法
使用ejs模块之前,首先需要进行导入,代码如下:
js
const ejs = require('ejs');
ejs模块提供了3个方法,用来渲染数据并生成HTML页面,下面分别介绍。
1.1.1、render()方法
对ejs代码进行渲染,语法格式如下:
js
render(str,data,options)
str:要渲染的ejs代码。data:可选的参数,表示渲染的数据,可以是对象或者数组。options:可选参数,指定一些用于解析模板时的变量,如编码方式等。
例如,使用fs.readFile()方法读取一个index.ejs文件,然后使用ejs.render()方法渲染读取的数据,并输出,代码如下:
js
//读取ejs模板文件
fs.readFile('index.ejs', 'utf8', (error, data)=>{
response.writeHead(200, {'Content-Type': 'text/html'});
//渲染数据并输出
response.end(ejs.render(data));
}
1.1.2、compile()方法
对指定数据进行渲染,语法格式如下:
js
ejs.compile(str,options)
str:渲染的数据展示区域。options:可选参数,表示一些额外的参数配置。
例如,下面代码用来对ejs代码内容进行渲染:
js
let season = ['spring', 'summer', 'autumn',"winter"]
let template = ejs.compile('<%= season.join(" 、 ") %>')
let html = template(people)
document.getElementById('app').innerHTML = html
1.1.3、renserFile()方法
对模板文件进行渲染,语法格式如下:
js
ejs.renderFile(filename,data,options,function(err,str){})
filename:ejs文件路径。data:渲染的数据,可以是对象或者数组。options:额外的参数配置,如编码格式等。err:渲染文件失败时的错误信息。str:渲染的数据展示区。
例如,下面代码用来直接渲染index.ejs文件并输出:
js
ejs.renderFile("index.ejs","utf8",(err,data)=>{
response.end(data)
});
1.2、ejs渲染示例
- 在WebStorm中创建一个.js文件,在该文件中引入http、fs、ejs模块,然后创建服务器,并在服务器中使用ejs.renderFile()方法读取并渲染index.ejs文件。代码如下:
js
//引入模块
const http = require('http');
const fs = require('fs');
const ejs = require('ejs');
//创建服务器
http.createServer((request, response)=>{
response.writeHead(200, {'Content-Type': 'text/html'});
//渲染ejs模板文件
ejs.renderFile('index.ejs', 'utf8', (error, data)=>{
response.end(data);
});
}).listen(52273, ()=>{
console.log('服务器监听端口是 http://127.0.0.1:52273');
});
- 创建index.html文件,并将文件的后缀名改为ejs,该文件主要作为一个简单的ejs模板文件,其中显示一行文字,代码如下:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用ejs渲染</title>
</head>
<body>
<h3 style="color: red">你看到的是一个HTML,<br>实际上是ejs转换来的</h3>
</body>
</html>
运行.js文件,在浏览器中输入网址http://127.0.0.1:52273/,浏览器中的效果如图所示。

1.3、ejs标签
ejs文件与HTML文件很相似,它们都使用HTML标签构建页面内容。不同的是,ejs文件中可以有一些特殊的渲染标识,以便进行动态数据渲染。在ejs文件中,可以使用以下标签表示一些特殊的含义。
<%:脚本标签,用于流程控制,无输出。<%_:删除其前面的空格符。<%=:输出数据到模板(输出是转义HTML标签)。<%-:输出非转义的数据到模板。<%#:注释标签,不执行、不输出内容。<%%:输出字符串'<%'。%>:一般结束标签。-%>:删除紧随其后的换行符。_%>:将结束标签后面的空格符删除。<% Code%>:输入JavaScript代码。<%=Value%>:输出数据,如字符串和数字等。
示例:将上节的index.ejs文件中的代码修改如下
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用ejs渲染</title>
</head>
<body>
<%
var today = new Date()
%>
<p><span>现在是:</span><span style="color: red"><%=today%></span></p>
</body>
</html>

示例:为客户端返回充值信息。
- 在WebStorm中创建一个.js文件,其中主要使用ejs.renderFile()方法渲染ejs模板文件并显示,代码如下:
js
//引入模块
const http = require('http');
const fs = require('fs');
const ejs = require('ejs');
//创建服务器
http.createServer((request, response)=>{
response.writeHead(200, { 'Content-Type': 'text/html' });
//渲染ejs模板文件
ejs.renderFile("index.ejs","utf8",(err,data)=>{
response.end(data)
});
}).listen(52273, ()=>{
console.log('服务器监听端口是 http://127.0.0.1:52273');
});
- 新建index.html文件,并将其后缀名修改为ejs,该文件中首先使用"<% Code%>"形式嵌入JavaScript代码,定义一些变量;然后使用"<%=Value%>"形式在页面中输出相应的变量。index.ejs文件中的代码如下:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>轨道交通充值信息</title>
<style>
.info{
margin:0 auto;
width:300px;
border: solid blue 1px;
color:blue
}
.info h3{
text-align: center;
border-bottom:dashed blue 1px
}
</style>
</head>
<body>
<% var title='轨道交通充值信息'%>
<% var A='东环城路'%>
<% var B='02390704'%>
<% var C='2023-03-03 11:32:15'%>
<% var D='19.50元'%>
<% var E='100.00元'%>
<% var F='119.50元'%>
<section class="info">
<h3><%=title%></h3>
<p>车站名称:<%=A%></p>
<p>设备编号:<%=B%></p>
<p>充值时间:<%=C%></p>
<p>交易前金额:<%=D%></p>
<p>充值金额:<%=E%></p>
<p>交易后金额:<%=F%></p>
</section>
</body>
</html>
运行.js文件,在浏览器中输入http://127.0.0.1:52273/,可以看到浏览器中的界面效果如图所示。

1.4、ejs的数据传递
要动态向ejs前端页面中传递数据,首先需要在ejs.render()方法中渲染要显示的数据时,定义要传递的数据;然后在ejs文件中使用"<%=Value%>"形式读取定义好的数据进行显示。这里需要注意的是,在读取定义好的数据时,如果数据是列表或者数组形式,要获取其中的某项内容,需要使用forEach遍历。
示例:显示美团外卖单据。
- 在WebStorm中创建一个.js文件,其中使用render()方法将自定义的No属性、orderTime属性和orderPrice属性渲染到index.ejs文件中。代码如下:
js
//引入模块
const http = require('http');
const fs = require('fs');
const ejs = require('ejs');
//创建服务器
http.createServer((request, response)=>{
//读取ejs模板文件
fs.readFile('index.ejs', 'utf8', (error, data)=>{
response.writeHead(200, {'Content-Type': 'text/html'});
response.end(ejs.render(data, {
No: '221#',
orderTime: '2023-04-10 12:10',
orderPrice: [{
menu: "锅包肉",
orderNo: '*1',
price: '27.00',
}, {
menu: "可乐",
orderNo: '*2',
price: '7.00',
}, {
menu: "合计",
orderNo: '',
price: '34.00',
}]
}));
});
}).listen(52273, ()=>{
console.log('服务器监听端口是 http://127.0.0.1:52273');
});
- 新建一个index.html文件,并将其后缀名修改为ejs,该文件中使用ejs渲染标识,将.js文件中渲染数据时自定义的属性分别显示到指定的HTML标签中。index.html文件中的代码如下:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>美团外卖</title>
<style>
*{
margin: 0 auto;
}
.info{
margin:0 auto;
width:300px;
border: solid blue 1px;
color:blue
}
.info h3{
text-align: center;
border-bottom:dashed blue 1px;
line-height: 40px;
}
.info p{
text-align: center;
border-bottom:dashed blue 1px;
line-height: 40px;
}
.info div{
text-align: center;
border-bottom:dashed blue 1px;
line-height: 40px;
}
.info table{
margin:0 auto;
text-align: center;
padding-bottom: 20px;
}
</style>
</head>
<body>
<section class="info">
<h3><%=No%> 美团外卖</h3>
<p>下单时间:<%=orderTime%></p>
<div>
送啥都快<br>
越吃越帅
</div>
<table>
<tr>
<td>菜品</td>
<td>数量</td>
<td>价格</td>
</tr>
<%orderPrice.forEach(function(item){%>
<tr>
<td><%=item.menu%></td>
<td><%=item.orderNo%></td>
<td><%=item.price%></td>
</tr>
<% }) %>
</table>
</section>
</body>
</html>
运行.js文件,在浏览器中输入http://127.0.0.1:52273/ ,可以看到浏览器中的界面效果如图所示。

2、pug模块
pug模块,原名jade,因版权问题,更名为pug,中文意思为"哈巴狗",它也是Web开发中常用的一种模板引擎。使用pug模块之前,首先需要使用npm命令进行下载和安装,命令如下:
js
npm install pug
2.1、基本语法
要使用pug模板引擎,必然需要用到pug文件,pug文件不同于html文件和ejs文件,它不需要标签的开和闭,比如html中的<p>Demo</p>,在pug中使用p Demo即可,因此本节首先带领大家熟悉一下pug文件的基本语法。
2.1.1、缩进
pug对空格敏感,这类似于Python对制表符(Tab)或者空格敏感的特点。pug使用空格作为缩进符,同一级标签需保证左对齐。例如:
html
div
p Hello, world!
p Hello, pug.
上面代码的渲染结果如下:
html
<div>
<p>Hellow, world!</p>
<p>Hello, pug.</p>
</div>
2.1.2、注释
pug使用//-或//对代码进行注释,前者注释内容不出现在渲染后的html文件中,后者反之。例如:
js
//- html中不包含此行
// html中会包含此行
2.1.3、属性
pug将标签属性存放于括号()内,多个属性之间以逗号或空格分隔。另外,对于标签的id和class属性,pug分别使用"#紧跟标签id"和".紧跟标签class"形式表示,而且可以同时设置多个class。例如:
js
h1#title Test title
img#name.class1.class2(src="/test.png" alt="test")
上面代码的渲染结果如下:
html
<h1 id="title">Test title</h1>
<img id="name" class="class1 class2" src="/test.png" alt="test">
2.1.4、包含
为了方便代码复用,pug提供了include包含功能。例如,下面代码会将_partial目录下的head.pug文件内容包含到当前调用的位置:
js
doctype html
html(lang='en')
include _partial/head.pug
2.1.5、定义变量
pug中通过"- var name = value"的形式定义变量,例如:
js
- var intData = 100
- var boolData = false
- var stringData = 'Test'
在引用变量时,需要在引用位置加上=号,否则会默认将变量名当成普通字符串使用。例如:
js
p.int= intData
p.bool= boolData
p.stringData= stringData
如果想要将变量与其他字符串常量或变量连接在一起,需要使用#{},该符号会对大括号内的变量进行求值和转义,最终得到输出的内容。例如:
js
- var girl = 'Lily'
- var boy = 'Jack'
p #{girl} is so beautiful!
p And #{boy} is handsome.
2.1.6、条件结构
pug的条件语句与其他语言的条件语句类似,形式如下:
js
- var A = {value: 'Test'}
- var B = true
if A.value
p= A.value
else if B
p= B
else
p nothing
2.1.7、循环结构
pug中使用each和while实现循环结构。其中,each可以返回当前所在项的索引值,默认从0开始计数。例如:
js
ol
each item in ['Sun', 'Mon', 'Tus', 'Wen', 'Thu', 'Fri', 'Sat']
li= item
- var week = ['Sun', 'Mon', 'Tus', 'Wen', 'Thu', 'Fri', 'Sat']
ol
each item, index in week
li= index + ':' + item
上面代码的渲染结果如下:
html
<ol>
<li>Sun</li>
<li>Mon</li>
<li>Tus</li>
<li>Wen</li>
<li>Thu</li>
<li>Fri</li>
<li>Sat</li>
</ol>
<ol>
<li>0:Sun</li>
<li>1:Mon</li>
<li>2:Tus</li>
<li>3:Wen</li>
<li>4:Thu</li>
<li>5:Fri</li>
<li>6:Sat</li>
</ol>
while使用方式如下:
js
- var day = 1
ul
while day < 7
li= day++
2.1.8、minix
mixin被称为混入,类似其他编程语言中的函数,也是为了代码复用,可带参数或不带参数,定义方式如下:
js
mixin menu-item(href, name)
li
span.dot
a(href=href)= name
其中,menu-item为调用时的名称,相当于函数名;href及name是参数。这里需要注意,a(href=href)= name中第二个=是为了将后面的name当作参数来处理,而不是当作字符串"name"来处理。
要调用mixin定义的代码块,需通过"+号紧跟mixin名称及参数"的形式,例如:
js
+menu-item('/Archives','Archives')
+menu-item('/About','About')
mixin之所以被称为混入,是因为其语法不局限于函数调用,在mixin内也可以使用block块,例如:
js
mixin print(post)
if block
block
else
p= post
+print("no block")
+print("")
div.box
p this is the content of block
上面代码的渲染结果如下:
html
<p>no block</p>
<div class="box"><p>this is the content of block</p></div>
2.1.9、 定义JavaScript代码
在pug中编写JavaScript代码时,需要使用以下形式:
js
script(type='text/javascript').
var data = "Test"
var enable = true
if enable
console.log(data)
else
console.log('nothing')
注意上面代码中第一行最后的"."符号。上面代码对应的JavaScript代码如下:
js
<script type='text/javascript'>
var data = "Test"
var enable = true
if enable
console.log(data)
else
console.log('nothing')
</script>
这里需要说明的是,对于简单脚本,使用pug尚可,而如果遇到复杂的JavaScript脚本,建议写在单独的.js文件中,然后通过pug引用,引用方式如下:
js
script(type='text/javascript', src='/path/to/js')
2.1.10、继承
pug支持继承,通过继承,也可以提高代码的复用率。例如,下面代码是一个简单的base模板,其中通过block定义了页面头部head和内容bod
js
//- base.pug
html
head
block title
body
block content
接下来就可以使用extends继承上面的模板,通过block覆盖或替换原有块block,代码如下:
js
//- index.pug
extends base.pug
block title
title "Test title"
block content
h1 Hello world!
block article
jade文件与pug文件"师出同门",其语法与pug文件一致,因此,如果遇到jade文件中的代码,可以参考上面语法进行解读。
2.2、pug的渲染方法
使用pug模块之前,首先需要进行导入,代码如下:
js
const pug = require('pug');
2.2.1、compile()
compile()方法用来把一个pug模板编译成一个可多次使用并能传入不同局部变量进行渲染的函数。语法格式如下:
string:要编译的pug模板。options:可选参数,指定一些用于解析模板的参数。返回值:一个根据本地配置生成的HTML字符串。
2.2.2、compileFile()
compileFile()方法用于从文件中读取一个pug模板文件,并编译成一个可多次使用并能传入不同局部变量进行渲染的函数。语法格式如下:
js
pug.compileFile(path, options)
path:要编译的pug文件路径。options:可选参数,配置渲染数据的相关参数。返回值:一个根据本地配置生成的HTML字符串。
2.2.3、compileClient()
compileClient()方法用于将一个pug模板编译成一份JavaScript代码字符串,以便在客户端调用,生成HTML。语法格式如下:
js
pug.compileClient(source, options)
source:要编译的pug模板。options:可选参数,用于配置编译数据的相关参数。返回值:一份JavaScript代码字符串。
2.2.4、compileClientWithDependenciesTracked()
该方法与compileClient()方法类似,但是其返回值为DOM对象,该方法适用于监视pug文件更改之类的操作。
2.2.5、compileFileClient()
compileFileClient()方法从文件中读取pug模板并编译成一份JavaScript代码字符串,它可以直接用在浏览器上而不需要pug的运行时库。语法格式如下:
js
pug.compileFileClient(path, options)
path:要编译的pug文件路径。options:可选参数,用于配置编译数据的相关参数,如果options中指定了name属性,那么它将作为客户端模板函数的名称。返回值:一份JavaScript代码字符串。
2.2.6、render()
render()方法用于渲染pug代码中的数据,并生成HTML代码,语法格式如下:
source:需要渲染的pug代码。options:存放可选参数的对象,同时也直接用作局部变量的对象。callback: Node.js风格的回调函数(注意:这个回调是同步执行的),用于接收渲染结果。返回值:渲染出来的HTML字符串。
2.2.7、renderFile()
renderFile()方法用于渲染pug文件中的数据,并生成HTML代码,语法格式如下:
js
pug.renderFile(path, options, callback)
path:string需要渲染的pug代码文件的位置。options:存放选项的对象,同时也直接用作局部变量的对象。callback:Node.js风格的回调函数(注意:这个回调是同步执行的),用于接收渲染结果。返回值:渲染出来的HTML字符串。
2.3、渲染示例
模拟获取消费券页面。
- 在WebStorm中创建一个.js文件,该文件的主要作用是创建服务器,以及从客户端获取数据并且使用pug模板引擎进行渲染。代码如下:
js
//引入模块
const http = require('http');
const pug = require('pug');
const fs = require('fs');
//创建服务器
http.createServer((request, response)=>{
//读取pug文件
fs.readFile('index.pug', 'utf8', (error, data){
//调用pug模块的compile方法解析pug模板代码
var fn = pug.compile(data);
response.writeHead(200, { 'Content-Type': 'text/html' });
response.end(fn());
});
}).listen(52273, ()=>{
console.log('服务器监听地址是 http://127.0.0.1:52273');
});
- 创建index.pug文件,该文件中主要使用pug语法设置页面中要显示的数据,代码如下:
html
doctype html
html
head
meta(charset="UTF-8")
title 微信支付
body
div(style={margin:'0 auto',width:'300px','line-height':'80px','border':'1px dashed #8bc34a'})
h3(style={'text-align':'center','line-height':'40px','margin':'0px 0px'}) 恭喜你获得指定商家消费券
p(style={'text-align':'center','color':'red','line-height':'40px','margin':'0px 0px'}) ¥3.66元
div(style={'text-align':'center','line-height':'40px'}) 已存入卡包,下次消费自动抵扣
div(style={'text-align':'center','line-height':'40px','font-size':'12px'}) 微众银行助力智慧生活
运行.js文件,在浏览器中输入http://127.0.0.1:52273/,可以看到浏览器中的界面效果如图所示。

2.4、pug的数据传递
要动态向pug模板传递数据,需要在服务器端输出渲染的数据时,通过自定义属性存储要传递给客户端的数据,然后在pug文件中使用#{}绑定服务器端自定义的相应属性。
月度消费账单提醒:
- 在WebStorm中创建一个.js文件,该文件中使用pub模块的compile()方法解析pug模板代码并显示,在显示时,将自定义的month、out和in1等属性返回给客户端。代码如下:
js
//引入模块
const http = require('http');
const pug = require('pug');
const fs = require('fs');
//创建服务器
http.createServer((request, response)=>{
//读取pug文件
fs.readFile('index.pug', 'utf8', (error, data)=>{
//调用pug模块的compile方法解析pug模板代码
let fn = pug.compile(data);
response.writeHead(200, { 'Content-Type': 'text/html' });
//向客户端返回信息
response.end(fn({
month: '2023年6月',
out:"520.10",
in1:3370.34,
transport:"120.00",
shopping:"300.00",
medical:87.10,
other: "13.00"
}));
});
}).listen(52273, ()=>{
console.log('服务器监听地址是 http://127.0.0.1:52273');
});
- 创建一个index.pug文件。在文件中,通过使用pug渲染标识,将服务器返回给客户端的自定义属性显示到指定的HTML标签中。代码如下:
html
doctype html
html
head
meta(charset="UTF-8")
title 手机账单提醒
body
div(style={margin:'0 auto',width:'300px',border:'solid blue 1px','padding':'20px'})
h3(style={'text-align':'center','margin-bottom':'0'}) 月度账单提醒
p(style={'text-align':'center','font-size':'12px','margin':'4px auto 10px'}) 月份: #{month}
p(style={'text-align':'center','font-size':'20px','margin':'0 auto','color':'#009688'}) 支出: #{out}
p(style={'text-align':'center','font-size':'12px','margin-top':'0'}) 收入: #{in1}
p
span 明细:
span(style={'color':'#009688','background':'rgba(156, 223, 244, 0.5)',
'border-radius':'5px','float':'right','font-size':'12px','padding':'5px 10px','margin-right':'5px'}) 支出
span(style={'color':'#2d2525','background':'rgba(170, 170, 170, 0.33)',
'border-radius':'5px','float':'right','font-size':'12px','padding':'5px 10px','margin-right':'5px'}) 收入
p
span 交通:
span(style={'float':'right'}) ¥ #{transport}
p
span 购物:
span(style={'float':'right'}) ¥ #{shopping}
p
span 医疗:
span(style={'float':'right'}) ¥#{medical}
p
span 其他:
span(style={'float':'right'}) ¥#{other}
运行.js文件,在浏览器中输入http://127.0.0.1:52273/,可以看到浏览器中的界面效果如图所示。
