您好,登錄后才能下訂單哦!
這篇文章主要介紹了Node中的模板引擎是什么,具有一定借鑒價(jià)值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。
在本文中,我們將介紹如何用Node.js
和Express
來(lái)使用 Handlebars 模板引擎。還會(huì)介紹什么是模板引擎,以及如何使用把 Handlebars 建服務(wù)器端渲染(SSR) web應(yīng)用程序。
我們還將討論如何使用 Express.js
框架配置 Handlebars ,以及如何使用內(nèi)置helpers
創(chuàng)建動(dòng)態(tài)頁(yè)面。最后,我們將了解如何在需要時(shí)開(kāi)發(fā)自定義helper
。
早在上世紀(jì)90年代,當(dāng)互聯(lián)網(wǎng)出現(xiàn)時(shí),它主要用于科學(xué)目的,比如發(fā)表研究論文,以及作為大學(xué)和科學(xué)家之間的溝通渠道。那時(shí)的大多數(shù)網(wǎng)頁(yè)都是靜態(tài)的。靜態(tài)web頁(yè)面對(duì)每個(gè)用戶都是相同的,不會(huì)根據(jù)每個(gè)用戶而改變,如果要更改頁(yè)面上的任何內(nèi)容,都必須手動(dòng)完成。
在現(xiàn)代世界中,事物的互動(dòng)性更強(qiáng),并且為每個(gè)用戶量身定制。今天,幾乎每個(gè)人都能訪問(wèn)互聯(lián)網(wǎng)?,F(xiàn)在的大多數(shù)web應(yīng)用程序都是動(dòng)態(tài)的。例如,在一些購(gòu)物網(wǎng)站上,不同用戶登錄的界面,展示是不一樣的,所謂的 千人千面。對(duì)于每個(gè)人來(lái)說(shuō),頁(yè)面將遵循相同的模板(即上面有用戶名的連續(xù)發(fā)布),但是內(nèi)容將是不同的。
模板引擎的工作內(nèi)容:定義展示內(nèi)容模板,然后根據(jù)當(dāng)前用戶和對(duì)數(shù)據(jù)庫(kù)的查詢,用接收到的內(nèi)容填充模板。
我們可以在后端和前端使用模板引擎。如果我們?cè)诤蠖耸褂媚0逡鎭?lái)生成HTML,這種方式叫做服務(wù)器端渲染(SSR)
。
Handlebars 在后端和前端模板中都很流行。例如,流行的前端框架Ember就是使用Handlebars
作為模板引擎。
Handlebars 是Mustache模板語(yǔ)言的擴(kuò)展,Mustache 模板語(yǔ)言主要專注于簡(jiǎn)單性和最小的模板。
首先,創(chuàng)建一個(gè)空文件夾,然后打開(kāi)終端,然后運(yùn)行npm init -y
以默認(rèn)配置建一個(gè)空的 Node.js 項(xiàng)目。
開(kāi)始之前,我們需要安裝所需的Node.js庫(kù)。 通過(guò)運(yùn)行以下命令來(lái)安裝express
和express-handlebars
模塊:
npm install --save express express-handlebars
注意:在服務(wù)器端使用 Handlebars
時(shí),你可能會(huì)使用一個(gè)像express-handlebars
這樣的幫助模塊,它將Handlebars
與web框架集成在一起。在本文中,我們主要關(guān)注模板語(yǔ)法,這也是我們使用express-handlebars
的原因,但是如果你自己處理模板編譯和渲染,還需要看 compilation API reference 對(duì)應(yīng)的文檔說(shuō)明。
然后,重新創(chuàng)建默認(rèn)的 Handlebars 目錄結(jié)構(gòu)。 views
文件夾包含所有Handlebars 手模板:
├── app.js └── views ├── home.hbs └── layouts └── main.hbs
views
文件夾內(nèi)的layouts
文件夾將包含布局或模板包裝器。 這些布局將包含模板之間共享的HTML結(jié)構(gòu),樣式表和腳本。
main.hbs
文件是主布局,home.hbs
文件是我們要構(gòu)建的示例Handlebars
模板。
在我們的示例中,我們使用一個(gè)腳本來(lái)保持簡(jiǎn)單性。首先,在app.js
文件中導(dǎo)入所需的庫(kù):
const express = require('express'); const exphbs = require('express-handlebars');
然后,創(chuàng)建一個(gè)Express app
const app = express();
現(xiàn)在,我們可以配置express-handlebars
作為我們的視圖引擎:
const express = require('express'); const exphbs = require('express-handlebars'); const app = express(); app.engine('hbs', exphbs({ defaultLayout: 'main', extname: '.hbs' })) app.set('view engine', 'hbs');
默認(rèn)情況下,Handlebars 模板的擴(kuò)展名是.handlebars
。 但是在這里的設(shè)置中,我們通過(guò)extname
標(biāo)志將其更改為.hbs
,因?yàn)樗獭?/p>
接著,在main.hbs
布局添加Bootstrap
腳本和樣式:
在home.hb
添加如下內(nèi)容:
<h2>Hello World from Handlebars</h2>
在 app.js
中添加對(duì)應(yīng)的路由配置:
app.get('/', (req, res) => { res.render('home'); });
然后,添加如果監(jiān)聽(tīng)的端口號(hào):
app.listen(3000, () => { console.log('The web server has started on port 3000'); });
這樣就可以在控制臺(tái)中運(yùn)行node app.js
啟動(dòng)應(yīng)用程序。
但是我們也可以選擇使用諸如nodemon之類的工具。 使用nodemon
,我們?cè)诟拇a時(shí)不需要每次都要重新啟動(dòng)服務(wù)器,nodemon
會(huì)自動(dòng)刷新服務(wù)器。
盤(pán)它:
npm i -g nodemon
安裝后,運(yùn)行:
nodemon app.js
在瀏覽器中打開(kāi) http://localhost:3000/
:
為了展示一些Handlebars
功能,我們將構(gòu)建一個(gè)社交媒體類的網(wǎng)站。 這里我們用一個(gè)簡(jiǎn)單的數(shù)組來(lái)模擬數(shù)據(jù)庫(kù)。
將home.hbs
內(nèi)容更新成如下:
<nav class="navbar navbar-dark bg-dark"> <a class="navbar-brand" href="#">Book Face</a> </nav> <p class="posts"> <p class="row justify-content-center"> <p class="col-lg-7" style="margin-top: 50px;"> <p class="card"> <img src="https://picsum.photos/500/500" class="card-img-top" alt="..."> <p class="card-body"> <h6 class="card-title">此文章由 前端小智 發(fā)布</h6> <ul class="list-group"> <li class="list-group-item">期待你們的留言/li> <li class="list-group-item">期待你們的留言</li> </ul> </p> </p> </p> </p> </p>
上面我們添加了一個(gè) navbar
和一個(gè)帖子的展示內(nèi)容 card
,運(yùn)行效果如下:
現(xiàn)在,讓我們從頁(yè)面本身中刪除這些硬編碼的值,這些值由路由傳遞進(jìn)來(lái), 在 app.js
中修改如下內(nèi)容 :
app.get('/', function (req, res) { res.render('home', { post: { author: '小智', image: 'https://picsum.photos/500/500', comments: [] } }); });
post 對(duì)象包含author
,image
和comments
等字段。 我們可以在 Handlebars模板使用{{post}}
來(lái)引用這些值:
<nav class="navbar navbar-dark bg-dark"> <a class="navbar-brand" href="#">Book Face</a> </nav> <p class="posts"> <p class="row justify-content-center"> <p class="col-lg-7" style="margin-top: 50px;"> <p class="card"> <img src="https://picsum.photos/500/500" class="card-img-top" alt="..."> <p class="card-body"> <h6 class="card-title">此文章由 {{post.author}} 發(fā)布</h6> <ul class="list-group"> <li class="list-group-item">期待你們的留言/li> <li class="list-group-item">期待你們的留言</li> </ul> </p> </p> </p> </p> </p>
效果如下:
由于這里需要一些邏輯判斷,即 comments
沒(méi)數(shù)據(jù)不顯示,我們看看如何在Handlebars 模板中使用條件:
<nav class="navbar navbar-dark bg-dark"> <a class="navbar-brand" href="#">Book Face</a> </nav> <p class="posts"> <p class="row justify-content-center"> <p class="col-lg-7" style="margin-top: 50px;"> <p class="card"> <img src="https://picsum.photos/500/500" class="card-img-top" alt="..."> <p class="card-body"> <h6 class="card-title">此文章由 {{post.author}} 發(fā)布</h6> {{#if post.comments}} <ul class="list-group"> </ul> {{else}} <ul class="list-group"> <li class="list-group-item">期待你們的留言</li> </ul> {{/if}} </p> </p> </p> </p> </p>
這里我們的 comments 為空,所以顯示了 期待你們的留言
。
#if
是把 Handlebars 的內(nèi)置幫助器。 如果if
語(yǔ)句返回true
,則將渲染#if
塊內(nèi)部的塊。 如果返回false
,undefined
,null
,""
,0
或[]
,則不會(huì)渲染該塊。
#if
僅接受一個(gè)條件,并且不能使用 JS 比較語(yǔ)法(===
)。 如果需要使用多個(gè)條件或其他語(yǔ)法,則可以在代碼中創(chuàng)建一個(gè)變量,然后將其傳遞給模板。 另外,你可以定義自己的 helper ,我們將在上一節(jié)中進(jìn)行操作。
由于帖子可以包含多個(gè)評(píng)論,因此我們需要一個(gè)循環(huán)渲染它們。 首先,我們先添加一些數(shù)據(jù):
app.get('/', function (req, res) { res.render('home', { post: { author: '小智', image: 'https://picsum.photos/500/500', comments: [ '前端小智終身學(xué)習(xí)者', '前端小智持續(xù)分享者', '雖然沒(méi)啥流量,但也希望你也能堅(jiān)持分享下去,幫助更多的初學(xué)者' ] } }); });
現(xiàn)在,在我們的模板中,使用#each
循環(huán)遍歷它們:
<nav class="navbar navbar-dark bg-dark"> <a class="navbar-brand" href="#">Book Face</a> </nav> <p class="posts"> <p class="row justify-content-center"> <p class="col-lg-7" style="margin-top: 50px;"> <p class="card"> <img src="https://picsum.photos/500/500" class="card-img-top" alt="..."> <p class="card-body"> <h6 class="card-title">此文章由 {{post.author}} 發(fā)布</h6> {{#if post.comments}} <ul class="list-group"> {{#each post.comments}} <li class="list-group-item">{{this}}</li> {{/each}} </ul> {{else}} <ul class="list-group"> <li class="list-group-item">期待你們的留言</li> </ul> {{/if}} </p> </p> </p> </p> </p>
在#each
循環(huán)中,可以使用this
來(lái)引用當(dāng)前迭代中的元素。在我們的示例中,它引用了一個(gè)隨后被渲染的字符串
如果posts
是一個(gè)對(duì)象數(shù)組,你也可以訪問(wèn)該對(duì)象的任何屬性。例如,如果有一個(gè)人員數(shù)組,你可以簡(jiǎn)單地使用this.name
來(lái)訪問(wèn)name
字段。
現(xiàn)在,為我們的 posts
添加多個(gè)數(shù)據(jù):
app.get('/', function (req, res) { res.render('home', { posts: [ { author: '小智', image: 'https://picsum.photos/500/500', comments: [ '前端小智終身學(xué)習(xí)者', '前端小智持續(xù)分享者', '雖然沒(méi)啥流量,但也希望你也能堅(jiān)持分享下去,幫助更多的初學(xué)者' ] }, { author: '前端大智', image: 'https://picsum.photos/500/500?2', comments: [] } ] }); });
然后,使用#each
來(lái)遍歷 posts
:
<p class="posts"> <p class="row justify-content-center"> {{#each posts}} <p class="col-lg-7" style="margin-top: 50px;"> <p class="card"> <img src="{{this.image}}" class="card-img-top" alt="..."> <p class="card-body"> <h6 class="card-title">此文章由 {{post.author}} 發(fā)布</h6> {{#if this.comments}} <ul class="list-group"> {{#each this.comments}} <li class="list-group-item">{{this}}</li> {{/each}} </ul> {{else}} <ul class="list-group"> <li class="list-group-item">期待你們的留言</li> </ul> {{/if}} </p> </p> </p> {{/each}} </p> </p>
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享Node中的模板引擎是什么內(nèi)容對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,遇到問(wèn)題就找億速云,詳細(xì)的解決方法等著你來(lái)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。