視頻地址:https://www.cctalk.com/v/15114923888328javascript
彩虹是上帝和人類立的約,上帝不會再用洪水滅人。
客戶端和服務端之間相互通訊,傳遞的數據最終都會展現在視圖中,這時候就須要用到『模板引擎』。css
模板引擎是爲了使用戶界面與業務數據分離而產生的,能夠生成特定格式的文檔。例如,用於網站的模板引擎會生成一個標準的 HTML
文檔。 html
市面上常見的模板引擎不少,例如:Smarty
、Jade
、Ejs
、Nunjucks
等,能夠根據我的喜愛進行選擇。koa-views
、koa-nunjucks-2
等支持 Koa
的第三方中間件也能夠自行選擇。 java
本項目中,咱們使用 koa-nunjucks-2
做爲模板引擎。Nunjucks
是 Mozilla
開發的,純 js
編寫的模板引擎,既能夠用在 Node
環境下,也能夠運行在瀏覽器端。koa-nunjucks-2
是基於 Nunjucks
封裝出來的第三方中間件,完美支持 Koa2
。git
首先咱們須要瞭解 Nunjucks
的幾個特性github
變量npm
{{ username }} {{ foo.bar }} {{ foo["bar"] }}
若是變量的值爲 undefined
或 null
,將不予顯示。 編程
過濾器小程序
{{ foo | title }} {{ foo | join(",") }} {{ foo | replace("foo", "bar") | capitalize }}
if
判斷微信小程序
{% if variable %} It is true {% endif %} {% if hungry %} I am hungry {% elif tired %} I am tired {% else %} I am good! {% endif %}
for
循環
var items = [{ title: "foo", id: 1 }, { title: "bar", id: 2}]
<h1>Posts</h1> <ul> {% for item in items %} <li>{{ item.title }}</li> {% else %} <li>This would display if the 'item' collection were empty</li> {% endfor %} </ul>
macro
宏
宏:定義可複用的內容,相似於編程語言中的函數
{% macro field(name, value='', type='text') %} <div class="field"> <input type="{{ type }}" name="{{ name }}" value="{{ value | escape }}" /> </div> {% endmacro %}
接下來就能夠把 field
看成函數同樣使用:
{{ field('user') }} {{ field('pass', type='password') }}
更多語法內容請查閱官方文檔
網頁常見的結構大可能是頭部、中間體加尾部,同一個網站下的多個網頁,頭部和尾部內容一般來講基本一致。因而咱們能夠採用繼承功能來進行編寫。
先定義一個 layout.html
<html> <head> {% block head %} <link rel="stylesheet"> {% endblock %} </head> <body> {% block header %} <h1>this is header</h1> {% endblock %} {% block body %} <h1>this is body</h1> {% endblock %} {% block footer %} <h1>this is footer</h1> {% endblock %} {% block content %} <script> //this is place for javascript </script> {% endblock %} </body> </html>
layout
定義了五個模塊,分別命名爲:head
、header
、body
、footer
、content
。header
和 footer
是公用的,所以基本不動。業務代碼的修改只須要在 body
內容體中進行、業務樣式表和業務腳本分別在頭部 head
和底部 content
中引入。
接下來咱們再定義一個業務級別的視圖頁面:home.html
{% extends 'layout.html' %} {% block head %} <link href="home.css"> {% endblock %} {% block body %} <h1>home 頁面內容</h1> {% endblock %} {% block content %} <script src="home.js"></script> {% endblock%}
最終的 home.html
輸出後以下所示:
<html> <head> <link href="home.css"> </head> <body> <h1>this is header</h1> <h1>home 頁面內容</h1> <h1>this is footer</h1> <script src="home.js"></script> </body> </html>
請對特殊字符進行轉義,防止 Xss
攻擊。若在頁面上寫入 Hello World<script>alert(0)</script>
這類字符串變量,而且不進行轉義,頁面渲染時該腳本就會自動執行,彈出提示框。
安裝 koa-nunjucks-2
:
npm i koa-nunjucks-2 -S
修改 app.js
,引入中間件,並指定存放視圖文件的目錄 views
:
const Koa = require('koa') const path = require('path') const bodyParser = require('koa-bodyparser') const nunjucks = require('koa-nunjucks-2') const app = new Koa() const router = require('./router') app.use(nunjucks({ ext: 'html', path: path.join(__dirname, 'views'),// 指定視圖目錄 nunjucksConfig: { trimBlocks: true // 開啓轉義 防Xss } })); app.use(bodyParser()) router(app) app.listen(3000, () => { console.log('server is running at http://localhost:3000') })
在以前的項目中,視圖被寫在了 controller/home
裏面,如今咱們把它遷移到 views
中:
新建 views/home/login.html
:
<!DOCTYPE html> <html lang="en"> <head> <title></title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <form action="/user/register" method="post"> <input name="name" type="text" placeholder="請輸入用戶名:ikcamp" /> <br/> <input name="password" type="text" placeholder="請輸入密碼:123456" /> <br/> <button>{{btnName}}</button> </form> </body> </html>
重寫 controller/home
中的 login
方法:
login: async(ctx, next) => { await ctx.render('home/login',{ btnName: 'GoGoGo' }) },
注意: 這裏咱們使用了 await
來異步讀取文件。由於須要等待,因此必須保證讀取文件以後再進行請求的響應。
增長了 views
層以後,視圖功能還不算完善,咱們還須要增長靜態資源目錄。固然,若是能直接使用靜態服務器的話更好。下一節中,咱們將講述下如何增長靜態文件及美化項目視圖。
下一篇:處理靜態資源——指定靜態文件目錄,設定緩存
上一篇:iKcamp新課程推出啦~~~~~ iKcamp|基於Koa2搭建Node.js實戰(含視頻)☞ 代碼分層