摘要:基本概念的基本概念十分簡單一個模板數據和傳統的字符串模板拼接非常相似例如我們有一個列表該列表展示一組新聞理想中的狀態如下新聞新聞新聞新聞新聞如果數據是異步獲取的我們可以利用循環拼接字符串來實現內部的多個然后再追加到中但是更像是如下的樣子偽代
基本概念
ejs的基本概念十分簡單,一個html = 模板 + 數據,和傳統的php字符串模板拼接非常相似.
例如我們有一個列表該列表展示一組新聞,理想中的狀態如下:
新聞1
新聞2
新聞3
新聞4
新聞5
如果數據是異步獲取的,我們可以利用for循環拼接字符串來實現內部的多個h2然后再追加到html中.
let data = [],result = ""; for (i=0,len = data.length;i"+data[i]+">"; }
但是ejs更像是如下的樣子(偽代碼):
/** * @param {string} template 字符串模板 * @param {object} data 模板需要的數據 */ function ejs(template,data) { return template(data); }
也就是說ejs需要一個字符串模板,和一個data也就是我們的數據源.
template是字符串模板基于html語法但是ejs提供了特殊符號用于控制我們傳入的數據如何填充到html中.
安裝這里就不提及了你可以去官網下載也可以使用npm進行安裝.
我使用的版本是2.6.1是目前的最新版本,網上的很多文章實際上有些已經過時了,因為API有些變動.
ejs中文文檔中有較新的API一覽.
使用ejs分為兩個版本一個是CommonJs版本,另外一個是AMD規范的版本.
后面的測試基本都是在瀏覽器中運行,我沒有使用requireJs直接使用script引入的ejs:
ejs會將自身掛載到window對象上,所以你只要console.log(ejs)控制臺有輸出就說明安裝成功了.
渲染單個數據ejs.render("<%= data %>
",{data:123});
返回:
123
render方法只需要兩個參數,和之前說的一樣第一個為模板字符串,而二個為數據源.
ejs使用html作為模板的基礎語言,所以你不需要進行學習任何額外的語法,需要了解的就是ejs給我們提供的幾個模板語法.
那么<%= %>目前看來就是輸出數據,ejs所做的僅僅是用123來替換掉<%= data %>而已.
渲染多個數據在ejs提供的語法中可以直接使用javascript所以你可以非常容易理解使用復雜邏輯如何完成渲染的,我們來看一個具體的例子:
const template = `<% news.forEach(item=>{ %> `; const data = { news:["新聞1","新聞2","新聞3"] }; const htmlString = ejs.render(template,data);<%= item %>
<% }) %>
返回的內容:
新聞1
新聞2
新聞3
實際上去除掉ejs提供了模板語法,內容就是這個樣子的:
news.forEach(item=>{ ""+item+"
" })
也就是說<% %>的符號不會產生實際的輸出,但是可以放置javascript代碼用于控制中間代碼塊的執行流程.
有條件的渲染數據const template = `<% data.forEach(item=>{ %> <% if(item.sexCode){ %> `; const data = { data:[ { name:"小明", sexCode:0 } , { name:"小紅", sexCode:1 } ] }; const htmlString = ejs.render(template,data);<%= item.name+"的性別是女" %>
<% } else { %><%= item.name+"的性別是男" %>
<% } %> <% }) %>
輸出:
小明的性別是男
小紅的性別是女
這個例子稍顯復雜,但是他告訴我們幾點有價值的內容:
<% %>用于存放javascript代碼片段是確定無疑的事情了,甚至在這個例子中我們還執行了嵌套操作.
<%= %>實際上把內容當作表達式執行后再輸出的,至少它有執行表達式的能力
本質<% %>用于執行其中的javascript代碼
<%= %>會對其中的javascript代碼html轉譯
其他的模板語法這里我就將官網的一覽貼了過來然后每個提供一個例子:
<% "腳本" 標簽,用于流程控制,無輸出。
<%_ 刪除其前面的空格符
<%= 輸出數據到模板(輸出是轉義 HTML 標簽)
<%- 輸出非轉義的數據到模板
<%# 注釋標簽,不執行、不輸出內容
<%% 輸出字符串 "<%"
%> 一般結束標簽
-%> 刪除緊隨其后的換行符
_%> 將結束標簽后面的空格符刪除
先看一下2,8,9這三個.
之前我的幾個例子中包含了很多空格和換行原因是因為使用的是默認的輸出格式,例如我們之前使用這個例子:
小明的性別是男
小紅的性別是女
來看一下修改后的效果.
使用刪除空格符號:
<%_ data.forEach(item=>{ _%> <%_ if(item.sexCode){ _%> <%= item.name+"的性別是女" _%>
<%_ } else { %><%= item.name+"的性別是男" _%>
<%_ } _%> <%_ }) _%>
輸出的內容:
小明的性別是男
小紅的性別是女
可以看到確實少了一些內容,但是實際上空隙是由換行符號引起的,這次我們來刪除尾部的換行符號:
<% data.forEach(item=>{ -%> <% if(item.sexCode){ -%> <%= item.name+"的性別是女" -%>
<% } else { -%><%= item.name+"的性別是男" -%>
<% } -%> <% }) -%>
輸出的內容:
小明的性別是男
小紅的性別是女
雖然行數減少了不過格式亂掉了.
注意:如果不想保留換行和空格可以把方法的選項參數中的rmWhitespace設置為true.
<%- %>的使用
默認情況下在<%= %>之間的html字符串會被做轉譯處理:
<%= "hello world
" %>
返回:
hello world
使用<%- %>:
該模板語法不會轉譯html字符串
<%- "hello world
" %>
返回:
hello world
<%# %>的使用
該標簽不會在最終的結果中出現,作為模板中的注釋:
<%# "hello world
" %>
返回的結果:
<%% %>的使用.
該操作返回的是模板字符串(string):
<%% if(id){ %> <%% } %>
返回的結果:
<% if(id){ %> <% } %>API
ejs渲染的API主要有三個分別是:
compile(str, options)
render(str, data, options)
renderFile(filename, data, options,callback(err,str)) 在瀏覽器端無效
區別是:
render 傳入模板字符串和數據返回結果
compile 返回一個模板函數,對這個函數傳入數據獲取結果
rednerFile 從文件中獲取模板
ejs內部是有緩存系統的它會將模板字符串解析為一個數據結構后續的操作將不會在此解析模板.
compile就是返回了內部已經處理好模板字符串的函數,在有大量數據重復使用這套模板的時候就會帶來性能提升,而對于render和renderFile來說需要在選項中設置cache為true,對于render方法還需要指定filename選項.
選項參數這里也是照搬官網的:
cache 緩存編譯后的函數,需要提供 filename
filename 被 cache 參數用做鍵值,同時也用于 include 語句
context 函數執行時的上下文環境
compileDebug 當為 false 時不編譯調試語句
client 返回獨立的編譯后的函數
delimiter 放在角括號中的字符,用于標記標簽的開與閉
debug 將生成的函數體輸出
_with 是否使用 with() {} 結構。如果為 false,所有局部數據將存儲在 locals 對象上。
localsName 如果不使用 with ,localsName 將作為存儲局部變量的對象的名稱。默認名稱是 locals
rmWhitespace 刪除所有可安全刪除的空白字符,包括開始與結尾處的空格。對于所有標簽來說,它提供了一個更安全版本的 -%> (在一行的中間并不會剔除標簽后面的換行符)。
escape 為 <%= 結構設置對應的轉義(escape)函數。它被用于輸出結果以及在生成的客戶端函數中通過 .toString() 輸出。(默認轉義 XML)。
root include使用絕對路徑引入時會以此為根路徑.
outputFunctionName 指定一個函數名稱(例如echo和print)用于在模板語法內打印輸出內容.
async 當為true時ejs內部的渲染都將為異步,內部使用(await/async).
測試緩存對于性能的影響,使用的模板和數據如下:
const template = `<% data.forEach(item=>{ %> <% if(item.sexCode){ %> `; const data = { data: [ { name: "小明", sexCode: 0 } , { name: "小紅", sexCode: 1 } ] };<%= item.name+"的性別是女" %>
<% } else { %><%= item.name+"的性別是男" %>
<% } %> <% }) %>
我使用render連續跑1000次使用的時間為480ms.
使用compile進行測試:
const demo = ejs.compile(template); console.time("start"); let i = 0, len = 1000; while (i < len) { demo(data); i++; } console.timeEnd("start");
最后的結果為15ms,可以看到性能提升是非常明顯的.
測試outputFunctionName選項.
const data = { content:"hello world" }; const result = ejs.render(`<% echo(content) %>
`,data,{ outputFunctionName:"echo" }); console.log(result)
輸出:
hello world
測試async選項.
const data = { content:"hello world" }; const result = ejs.render(`<%= content %>
`,data,{ async:true }); result.then((result)=>{ console.log(result); })
輸出:
瀏覽器端使用默認緩存hello world
網上的各種文章中都提到了ejs擁有內部緩存,給render方法提供選項中包含filename和cache屬性就可以以filename進行命名然后掛載在ejs內部的緩存對象上.
但是各個文章描述的及其模糊,我查看render和compile的源碼后也沒有發現顯式使用緩存的選項存在,不過依然找到了一個可以使用緩存后的函數的方法.
// 不要這次的結果,使用緩存 ejs.render(template,data,{ filename: "test", cache:true }); // 獲取緩存后的函數 const cacheFun = ejs.cache.get("test"); console.time("start"); let i = 0, len = 1000; while (i < len) { cacheFun(data); i++; } console.timeEnd("start");
最后使用的時間為15ms和使用compile的速度一致.
個人猜測內部緩存功能是為了服務端渲染使用的或者為了配合express使用,沒有向瀏覽器端提供很好的支持.
注意:ejs.clearCache()方法可以清空內部的緩存.
高級操作 包含其他模板在一般的開發中我們經常將網頁切割為多個部分,例如最簡單的切割就是將頁面分為導航欄`主體區域`頁尾三個部分.
在使用的時候經常變化的是主體區域,而頁尾不經常變化,但是很多頁面需要同樣的頁尾,這個時候我們就可以將頁尾多帶帶拿出來做成一個模板.
ejs中可以使用include命令來插入其他的模板.(注意只能在服務端中操作)
新建兩個文件:
header.ejs:
<%= content %>
footer.ejs:
<%= content %>
我們編寫以下代碼:
const ejs = require("ejs"); const template = ` <%- include("./header",{content:"我是頁頭"}) %>我是內容區域 <%- include("./footer",{content:"我是頁腳"}) %> `; console.log(ejs.render(template,{ filename:"whatthefuck" // 這個操作中需要一個名稱,和路徑無關 }));
輸出:
我是頁頭
我是內容區域 我是頁腳
有其他需要的朋友可以去查看ejs的github或者中文官網,唯一的額外信息也就這里有了.
參考https://blog.csdn.net/xjl2713...https://www.jianshu.com/p/81e...
https://blog.csdn.net/zhangxi...
https://www.cnblogs.com/yedey...
https://segmentfault.com/a/11...
https://ejs.bootcss.com/
https://github.com/mde/ejs
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99038.html
摘要:而框架中最常用的兩個視圖引擎是和。實際上這些上下文對象就是會在視圖中使用到的變量。其實視圖緩存并不是緩存視圖實際上它緩存的視圖路徑。根據默認視圖引擎將缺少拓展名的視圖文件補充完整。實際上存在由不同組織維護的兩個不同版本的。 showImg(https://segmentfault.com/img/remote/1460000010821004);前面的內容大都是關于 Express 框...
摘要:最近在看,讀完官方的起步教程后想著該自己折騰點東西,就先用實現一個超簡單的,主要記錄下思路。先推薦一個入門級的簡單實戰項目地址。不過鑒于初學,自身的思路肯定不會是最佳實踐,慢慢積累。 最近在看node.js,讀完官方的起步教程后想著該自己折騰點東西,就先用express + ejs實現一個超簡單的webserver,主要記錄下思路。先推薦一個nodejs入門級的簡單實戰項目地址。很適合...
摘要:安裝完畢后,打開終端,在終端分別輸入如下命令,檢測是否安裝成功。號會告訴安裝最新版本。它會為每一條記錄創建一個唯一的值。注意我們不需要提前創建這個,它會在第一次使用的時候自動創建。我們可以使用,這是我最常用的方式。 60分鐘學會使用Node.js+Express+Ejs+mongoDB 本文出自從零到壹全棧部落 (Node+Vue+微信公眾號開發)企業級產品全棧開發速成周末班首期班(1...
閱讀 3762·2021-09-22 15:17
閱讀 1946·2021-09-22 14:59
閱讀 2346·2020-12-03 17:00
閱讀 3209·2019-08-30 15:55
閱讀 482·2019-08-30 11:23
閱讀 3487·2019-08-29 13:56
閱讀 518·2019-08-29 12:54
閱讀 2257·2019-08-29 12:49