Node.js——Web模板引擎

Web模板引擎

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渲染示例

  1. 在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');
});
  1. 创建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>

示例:为客户端返回充值信息。

  1. 在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');
});
  1. 新建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遍历。

示例:显示美团外卖单据。

  1. 在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');
});
  1. 新建一个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、渲染示例

模拟获取消费券页面。

  1. 在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');
});
  1. 创建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文件中使用#{}绑定服务器端自定义的相应属性。

月度消费账单提醒:

  1. 在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');
});
  1. 创建一个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/,可以看到浏览器中的界面效果如图所示。

相关推荐
skywalk81632 小时前
Kotti Next的tinyfrontend前端模仿Kotti 首页布局(使用CodeArts)
前端
坐吃山猪2 小时前
TypeScript编程03-枚举
前端·javascript·typescript
小陈工2 小时前
Python Web开发入门(九):权限管理与角色控制实战
服务器·开发语言·前端·数据库·python·安全·sqlite
DFT计算杂谈2 小时前
eDMFT安装教程
java·服务器·前端·python·算法
Gazer_S2 小时前
【GitLab npm Registry 非标准端口安装问题解决方案】
前端·npm·gitlab
Aliex_git2 小时前
前端监控笔记(二)
前端·笔记·学习
光影少年2 小时前
实现发布订阅模式
前端·javascript·设计模式
雪碧聊技术2 小时前
linux下载node.js(这里面已经包含了npm)
npm·node.js
chushiyunen2 小时前
python web框架streamlit
开发语言·前端·python