1.模板引擎的基礎概念
1.1 模板引擎
模板引擎是 node.js 提供的第三方模塊。
讓開發者以更加友好的方式拼接字符串,使項目代碼更加清晰、更加易於維護。
// 未使用模板引擎的寫法 var ary = [{ name: '張三', age: 20}]; var str = '<ul>'; for(var i = 0; i< ary.length; i++) { str += '<li>\ <span>'+ ary[i].name + '</span>\ <span>'+ ary[i].age + '</span>\ </li>'; } str += '</ul>'; // 使用模板引擎的寫法 <ul> {{each ary}} <li>{{$value.name}}</li> <li>{{$value.age}}</li> {{/each}} </ul>
1.2 art-template 模板引擎
1、在命令行工具中使用 npm install art-template 命令進行下載
2、在項目中引入模板引擎
const template = require('art-template')
3、告訴模板引擎要拼接的數據和模板在哪
const html = template('模板路徑', 數據);
1.3 art-template 代碼示例
// 導入模板引擎模塊 const template = require('art-template'); // 將特定模板與特定數據進行拼接 const html = template('./views/index.art', { data: { name: '張三', age: 20 } })
模板中代碼:
<div> <span>{{data.name}}</span> <span>{{data.age}}</span> </div>
例子:
新建 template 文件夾,然后在命令行工具中切換到 template 目錄,下載 art-template :
npm install art-template
安裝完成后,新建 app.js 文件,導入模板引擎:
// 導入模板引擎 const template = require('art-template');
創建 views 文件夾,並新建 index.art 文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> </body> </html>
回到 app.js 文件中:
// 導入模板引擎 const template = require('art-template'); const path = require('path'); const viwes = path.join(__dirname, 'views', 'index.art') // template 方法是用來拼接字符串 // 第1個參數:模板路徑,絕對路徑 (__dirname 當前文件所在的路徑) // 第2個參數,要顯示的數據,對象類型 // 返回拼接好的字符串 const html = template(viwes, { name: '張三', age: 20 }) console.log(html)
打開 views/index.art 文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> {{name}} {{age}} </body> </html>
打開命令行工具,輸入:
node app.js
結果可以看到:
2.模板引擎語法
2.1、模板語法
● art-template 同時支持兩種模板語法:標准語法和原始語法。
● 標准語法可以讓模板更容易讀寫,原始語法具有強大的邏輯處理能力。.
2.2、輸出
將某項數據輸出在模板中,標准語法和原始語法如下:
標准語法:
{{ 數據 }}
原始語法:
<%= 數據 %>
例如:
<!-- 標准語法 --> <h2>{{value}}</h2> <h2>{{a ? b : c}}</h2> <h2>{{a + b}}</h2> <!-- 原始語法 --> <h2><%= value %></h2> <h2><%= a ? b : c %></h2> <h2><%= a + b %></h2>
例子:新建 01js 文件:
// 導入模板引擎 const template = require('art-template'); const path = require('path'); const views = path.join(__dirname, 'views', '01.art') // template 方法是用來拼接字符串 // 第1個參數:模板路徑,絕對路徑 (__dirname 當前文件所在的路徑) // 第2個參數,要顯示的數據,對象類型 // 返回拼接好的字符串 const html = template(viwes, { name: '張三', age: 20 }) console.log(html)
01.art 文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- 標准語法 --> <p>{{ name }}</p> <!-- 原始語法 --> <p><%= name %></p> </body> </html>
到命令行工具中運行 node 01.js
可以看到:不管是標准語法還是原始語法,都可以輸出“張三”’
修改下 01.art 文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <!-- 標准語法 --> <p>{{ name }}</p> <p>{{ 1 + 1 }}</p> <!-- 原始語法 --> <p><%= name %></p> <p><%= 1 + 2 %></p> </body> </html>
在命令行工具中重新運行 01.js,可以看到標准語法中輸出:2,原始語法中輸出:3
打開 01.js 文件,增加 content:
// 導入模板引擎 const template = require('art-template'); const path = require('path'); const views = path.join(__dirname, 'views', '01.art') // template 方法是用來拼接字符串 // 第1個參數:模板路徑,絕對路徑 (__dirname 當前文件所在的路徑) // 第2個參數,要顯示的數據,對象類型 // 返回拼接好的字符串 const html = template(viwes, { name: '張三', age: 20, content: '<h1>我是標題</h1>' }) console.log(html)
修改 01.art 文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <!-- 標准語法 --> <p>{{ name }}</p> <p>{{ 1 + 1 }}</p> <p>{{ 1 + 1 == 2 ? '相等' : '不相等' }}</p> {{ content }} <!-- 原始語法 --> <p><%= name %></p> <p><%= 1 + 2 %></p> <p><%= 1 + 1 == 2 ? '相等' : '不相等' %></p> <%= content %> </body> </html>
結果是:
模板引擎認為:默認情況下如果數據中帶標簽,是不會解析出來的,因為這是處於安全性的考慮。如果說你確定當前數據變量中的標簽是安全的,那么可以進行原文輸出,讓模板引擎解析。
2.3、原文輸出
標准語法:
{{@ 數據 }}
原始語法:
<%- 數據 %>
例子:下面我們把 01.art 文件中的數據改為原文輸出:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <!-- 標准語法 --> <p>{{ name }}</p> <p>{{ 1 + 1 }}</p> <p>{{ 1 + 1 == 2 ? '相等' : '不相等' }}</p> {{ content }} {{@ content }} <!-- 原始語法 --> <p><%= name %></p> <p><%= 1 + 2 %></p> <p><%= 1 + 1 == 2 ? '相等' : '不相等' %></p> <%= content %> <%- content %> </body> </html>
重新運行后可以看到:
注意:當數據中攜帶 HTML 標簽,默認模板引擎不會解析標簽;如果你確定數據中的標簽是安全的,那么可以使用原文輸出的方式對標簽進行解析。
2.4、條件判斷
在模板中可以根據條件來決定顯示那塊 HTML 代碼。
標准語法:
<!-- 標准語法 --> {{if 條件}} ... {{/if}} {{if v1}} ... {{else if v2}} ... {{/if}}
例子:新建 02.js 文件:
// 導入模板引擎 const template = require('art-template'); const path = require('path'); const views = path.join(__dirname, 'views', '02.art') // template 方法是用來拼接字符串 // 第1個參數:模板路徑,絕對路徑 (__dirname 當前文件所在的路徑) // 第2個參數,要顯示的數據,對象類型 // 返回拼接好的字符串 const html = template(views, { name: '張三', age: 20 }) console.log(html);
新建 02.art 文件:
{{if age > 18}}
年齡大於18
{{/if}}
在命令行工具中輸入:node 02.js
可以看到結果輸出是: 年齡大於18
修改 02.js 文件的年齡為:17
修改 02.art 文件:
{{if age > 18}} 年齡大於18 {{else if age < 15 }} 年齡小於15 {{else}} 年齡不符合要求 {{/if}}
在命令行工具中輸入:node 02.js
可以看到結果輸出是: 年齡不符合要求
原始語法:
<!-- 原始語法 --> <% if (value){ %> ... <% } %> <% if (v1){ %> ... <% } else if (v2) { %> ... <% } %>
例子:修改 02.art 文件:
{{if age > 18}} 年齡大於18 {{else if age < 15 }} 年齡小於15 {{else}} 年齡不符合要求 {{/if}} <% if (age > 18) { %> 年齡大於18 <% } else if (age < 15) { %> 年齡小於15 <% } else { %> 年齡不符合要求 <% } %>
重新運行 02.js 文件,
可以看到結果:
2.5、循環
標准語法:
{{each 數據}}{{/each}}
原始語法:
<% for() { %><% } %>
示例代碼:
<!-- 標准語法 --> {{each target}} {{ $index }} {{$value}} {{/each}} <!-- 原始語法 --> <% for(var i = 0; i < target.length; i++) { %> <%= i %> <% target[i] %> <% } %>
例子:新建 03.js 文件:
// 導入模板引擎 const template = require('art-template'); const path = require('path'); const views = path.join(__dirname, 'views', '03.art') // template 方法是用來拼接字符串 // 第1個參數:模板路徑,絕對路徑 (__dirname 當前文件所在的路徑) // 第2個參數,要顯示的數據,對象類型 // 返回拼接好的字符串 const html = template(views, { users: [ {name: '張三', age: 20, sex: '男'}, {name: '李四', age: 30, sex: '男'}, {name: '瑪麗', age: 15, sex: '女'}, ] }) console.log(html);
新建 03.art 文件:
<ul> {{each users}} <li> {{$value.name}} {{$value.age}} {{$value.sex}} </li> {{/each}} </ul>
運行后可以看到:
下面寫個原始語法的循環,繼續修改 03.art 文件:
<ul> {{each users}} <li> {{$value.name}} {{$value.age}} {{$value.sex}} </li> {{/each}} </ul> <ul> <% for (var i = 0; i< users.length; i++) { %> <li> <%= users[i].name %> <%= users[i].age %> <%= users[i].sex %> </li> <% } %> </ul>
重新運行后的結果還是和剛才一樣。
2.6、子模板
使用子模板可以將網站公共區塊(頭部、底部)抽離到單獨的文件中。
標准語法:
{{include "模板"}}
原始語法:
<% include("模板") %>
示例代碼:
<!-- 標准語法 --> {{include "。/header.art"}} <!-- 原始語法 --> <% include("./header.art") %>
例子:新建 04.js 文件:
// 導入模板引擎 const template = require('art-template'); const path = require('path'); const views = path.join(__dirname, 'views', '04.art') // template 方法是用來拼接字符串 // 第1個參數:模板路徑,絕對路徑 (__dirname 當前文件所在的路徑) // 第2個參數,要顯示的數據,對象類型 // 返回拼接好的字符串 const html = template(views, { msg: '我是首頁' }); console.log(html);
在 views 目錄下,新建 common 文件夾,用來存放公共模板。並創建 header.art 和 footer.art文件:
<!-- header.art --> 我是頭部 <!-- fotter.art--> 我是底部
在 views 目錄下,新建 04.art 文件:
{{ include './common/header.art' }} <div> {{ msg }} </div> {{ include './common/footer.art' }}
回到命令工具,運行 node 04.js
結果是:
再在 04.art 中寫下原始語法引用模板:
{{ include './common/header.art' }} <% include('./common/header.art') %> <div> {{ msg }} </div> {{ include './common/footer.art' }} <% include('./common/footer.art') %>
結果也是可以一樣顯示。
2.7、模板繼承
使用模板繼承可以將網站 HTML 骨架抽離到單獨的文件中,其他頁面模板可以繼承骨架文件。
2.8、模板繼承示例
骨架文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>HTML骨架模板</title> {{block 'head'}}{{/block}} </head> <body> {{block 'content'}}{{/block}} </body> </html>
其他頁面繼承骨架:
<!-- index.art 首頁模板 --> {{extend './layout.art'}} {{block 'head'}}<link rel="stylesheet" href="custom.css">{{/block}} {{block 'content'}}<div>This is just an awesome page.</div>{{/block}}
例子:新建 05.js 文件:
// 導入模板引擎 const template = require('art-template'); const path = require('path'); const views = path.join(__dirname, 'views', '05.art') // template 方法是用來拼接字符串 // 第1個參數:模板路徑,絕對路徑 (__dirname 當前文件所在的路徑) // 第2個參數,要顯示的數據,對象類型 // 返回拼接好的字符串 const html = template(views, { msg: '首頁模板' }); console.log(html);
在 common 目錄下中 新建 layout.art 文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> {{block 'link'}} {{/block}} </head> <body> {{block 'content'}} {{/block}} </body> </html>
在 views 目錄下新建 05.art 文件:
{{extend './common/layout.art'}} {{block 'link'}} <link rel="stylesheet" type="text/css" href="./main.css"> {{/block}} {{block 'content'}} <p>{{ msg }}</p> {{/block}}
回到命令行工具運行 node 05.js
結果可以看到:
2.9、模板配置
1、向模板中導入變量 template.defaults.imports.變量名 = 變量值;
dateformat 處理時間格式
https://www.npmjs.com/package/dateformat
下載安裝:
npm install dateformat
例子:新建 06.js 文件:
// 導入模板引擎 const template = require('art-template'); const path = require('path'); var dateFormat = require('dateformat'); const views = path.join(__dirname, 'views', '06.art') // template 方法是用來拼接字符串 // 第1個參數:模板路徑,絕對路徑 (__dirname 當前文件所在的路徑) // 第2個參數,要顯示的數據,對象類型 // 返回拼接好的字符串 const html = template(views, { time: new Date() }); console.log(html);
新建 06.art 文件,元輸出原始的日期時間:
{{ time }}
在命令行運行 node 06.js
結果是:
" 代碼引號
下面對日期時間進行處理,修改 06.js 文件:
// 導入模板引擎 const template = require('art-template'); const path = require('path'); var dateFormat = require('dateformat'); const views = path.join(__dirname, 'views', '06.art') // 導入模板變量 template.defaults.imports.dateFormat = dateFormat; // template 方法是用來拼接字符串 // 第1個參數:模板路徑,絕對路徑 (__dirname 當前文件所在的路徑) // 第2個參數,要顯示的數據,對象類型 // 返回拼接好的字符串 const html = template(views, { time: new Date() }); console.log(html);
修改 06.art 文件:
{{ dateFormat(time) }}
重新運行后可以看到結果:
也可以自定義格式:
{{ dateFormat(time, "yyyy-mm-dd") }}
結果是:
2、設置模板根目錄 template.defaults.root = 模板目錄
修改 06.js 文件:
// 導入模板引擎 const template = require('art-template'); const path = require('path'); var dateFormat = require('dateformat'); // 設置模板根目錄 template.defaults.root = path.join(__dirname, 'views') // 導入模板變量 template.defaults.imports.dateFormat = dateFormat; // template 方法是用來拼接字符串 // 第1個參數:模板路徑,絕對路徑 (__dirname 當前文件所在的路徑) // 第2個參數,要顯示的數據,對象類型 // 返回拼接好的字符串 const html = template('06.art', { time: new Date() }); console.log(html);
在命令工具中重新運行 node 06.js ,看到果還是一樣的。
3、設置模板默認后綴 template.defaults.extname = '.art'
還是修改 06.js 文件:
// 導入模板引擎 const template = require('art-template'); const path = require('path'); var dateFormat = require('dateformat'); // 設置模板根目錄 template.defaults.root = path.join(__dirname, 'views') // 導入模板變量 template.defaults.imports.dateFormat = dateFormat; // 配置模板的牧人后綴 template.defaults.extname = '.art'; // template 方法是用來拼接字符串 // 第1個參數:模板路徑,絕對路徑 (__dirname 當前文件所在的路徑) // 第2個參數,要顯示的數據,對象類型 // 返回拼接好的字符串 const html = template('06', { time: new Date() }); console.log(html);
在命令工具中重新運行 node 06.js ,看到果還是一樣的。
還可以更改文件的后綴
在 views 目錄下創建 07.html 文件:
我是07.html模板
修改 06.js 文件:
// 導入模板引擎 const template = require('art-template'); const path = require('path'); var dateFormat = require('dateformat'); // 設置模板根目錄 template.defaults.root = path.join(__dirname, 'views') // 導入模板變量 template.defaults.imports.dateFormat = dateFormat; // 配置模板的牧人后綴 template.defaults.extname = '.html'; // template 方法是用來拼接字符串 // 第1個參數:模板路徑,絕對路徑 (__dirname 當前文件所在的路徑) // 第2個參數,要顯示的數據,對象類型 // 返回拼接好的字符串 const html = template('06.art', { time: new Date() }); console.log(template('07', {})); console.log(html);
重新運行 node 06.js 的結果:
3.案例
3.1、案例介紹-學生檔案管理
目標:模板引擎應用,強化 node.js 項目制作流程。
知識點:http請求響應、數據庫、模板引擎、靜態資源訪問。
3.2、制作流程
1、建立項目文件夾並生成項目描述文件 package.json
2、創建網站服務器,實現客戶端和服務器端通信
3、連接數據庫並根據需求設計學員信息表
4、創建路由並實現頁面模板呈現
5、實現靜態資源訪問
6、實現學生信息添加功能
7、實現學生信息展示功能
https://www.cnblogs.com/joe235/p/12895747.html
3.3、第三方模塊 router
功能:實現路由。
使用步驟:
1、獲取路由對象
2、調用路由對象提供的方法創建路由
3、啟用路由,使路由生效
示例代碼:
const getRouter = require('router'); const router = getRouter(); router.get('/add', (req, res) => { res.end('hello world') }) server.on('request', (req. res) => { router(req, res) })
下載安裝:
npm install router
引入 router 模塊:
// 引入 router 模塊 const getRouter = require('router'); // 獲取路由對象 const router = getRouter();
創建路由:
router.get('/test', (req, res) => { res.end('test') }) router.get('/index', (req, res) => { res.end('index') })
使用路由:
// 當客戶端訪問服務器端的時候 app.on('request', (req, res) => { // res.end('ok'); router(req, res, () => {}) });
3.4、第三方模塊 serve-static
功能:實現靜態資源訪問服務。
步驟:
1、引入 serve-static 模塊獲取創建靜態資源服務功能的方法
2、調用方法創建靜態資源服務並指定靜態資源服務目錄
3、啟動靜態資源服務功能
示例代碼:
const serveStatic = require('serve-static') const serve = serveStatic('public') server.on('request', () => { serve(req. res) }) server.listen(3000)
下載安裝:
npm install serve-static
// 引入靜態資源訪問模塊 const serveStatic = require('serve-static');
實現靜態資源訪問服務:
// 實現靜態資源訪問服務 const serve = serveStatic('public')
啟用靜態資源訪問服務功能:
serve(req, res, () => {})