iKcamp|基於Koa2搭建Node.js實戰(含視訊)☞ 檢視Nunjucks

iKcamp發表於2018-01-08

視訊地址:www.cctalk.com/v/151149238…

iKcamp|基於Koa2搭建Node.js實戰(含視訊)☞ 檢視Nunjucks

檢視 Nunjucks

彩虹是上帝和人類立的約,上帝不會再用洪水滅人。

客戶端和服務端之間相互通訊,傳遞的資料最終都會展示在檢視中,這時候就需要用到『模板引擎』。

什麼是模板引擎?

模板引擎是為了使使用者介面與業務資料分離而產生的,可以生成特定格式的文件。例如,用於網站的模板引擎會生成一個標準的 HTML 文件。

市面上常見的模板引擎很多,例如:SmartyJadeEjsNunjucks 等,可以根據個人喜好進行選擇。koa-viewskoa-nunjucks-2 等支援 Koa 的第三方中介軟體也可以自行選擇。

本專案中,我們使用 koa-nunjucks-2 作為模板引擎。NunjucksMozilla 開發的,純 js 編寫的模板引擎,既可以用在 Node 環境下,也可以執行在瀏覽器端。koa-nunjucks-2 是基於 Nunjucks 封裝出來的第三方中介軟體,完美支援 Koa2

Nunjucks 介紹

首先我們需要了解 Nunjucks 的幾個特性

簡單語法

變數

  {{ username }}

  {{ foo.bar }}
  {{ foo["bar"] }}
複製程式碼

如果變數的值為 undefinednull ,將不予顯示。

過濾器

  {{ 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 定義了五個模組,分別命名為:headheaderbodyfootercontentheaderfooter 是公用的,因此基本不動。業務程式碼的修改只需要在 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|基於Koa2搭建Node.js實戰(含視訊)☞ 檢視Nunjucks

iKcamp|基於Koa2搭建Node.js實戰(含視訊)☞ 檢視Nunjucks

上一篇:iKcamp新課程推出啦~~~~~iKcamp|基於Koa2搭建Node.js實戰(含視訊)☞ 程式碼分層

推薦: 翻譯專案Master的自述:

1. 乾貨|人人都是翻譯專案的Master

2. iKcamp出品微信小程式教學共5章16小節彙總(含視訊)


iKcamp|基於Koa2搭建Node.js實戰(含視訊)☞ 檢視Nunjucks

2019年,iKcamp原創新書《Koa與Node.js開發實戰》已在京東、天貓、亞馬遜、噹噹開售啦!

相關文章