一文解析Express框架view對(duì)象使用
Expess View 從指定渲染引擎開始
以 mustache 渲染引擎為例,需要初始化一些代碼
const app = express()
app.set("view engine", "mustache");
app.engine("mustache", mustacheExpress());
app.set("views", toAbsolutePath("./views"));
- 指定視圖引擎
- 指定引擎工具
- 指定視圖位置
安裝依賴
pnpm install mustache mustache-express
從 res.render 函數(shù)開始
render 函數(shù)接收兩個(gè)參數(shù),第一個(gè) view 的路徑,第二個(gè)渲染數(shù)據(jù)。
res.render = function render(view, options, callback) {
// 調(diào)用 app.render
app.render(view, opts, done);
};
下面是 app.render 代碼實(shí)現(xiàn)
app.render = function render(name, options, callback) {
// view
if (!view) {
var View = this.get('view');
view = new View(name, {
defaultEngine: this.get('view engine'),
root: this.get('views'),
engines: engines
});
if (!view.path) {
var dirs = Array.isArray(view.root) && view.root.length > 1
? 'directories "' + view.root.slice(0, -1).join('", "') + '" or "' + view.root[view.root.length - 1] + '"'
: 'directory "' + view.root + '"'
var err = new Error('Failed to lookup view "' + name + '" in views ' + dirs);
err.view = view;
return done(err);
}
// prime the cache
if (renderOptions.cache) {
cache[name] = view;
}
}
// render
tryRender(view, renderOptions, done);
};
在 view 不在的情況下,會(huì)用 View 實(shí)例化 view, 最后調(diào)用 tryRender 函數(shù),tryRender 函數(shù)會(huì)調(diào)用 view.render 方法:
View 的實(shí)現(xiàn)
module.exports = View;
function View(name, options) {
// store loaded engine
this.engine = opts.engines[this.ext];
// lookup path
this.path = this.lookup(fileName);
}
跟一般的構(gòu)造函數(shù)一樣,初始化一些屬性,用傳入的 opts 合并一些屬性。
- View 擴(kuò)展方法
View.prototype.lookup = function lookup(name) {}
View.prototype.render = function render(options, callback) {
this.engine(this.path, options, callback);
}
View.prototype.resolve = function resolve(dir, file) {}
render 的具體實(shí)現(xiàn)就交給第三方引擎來實(shí)現(xiàn)了。
mustache 的render 方法的實(shí)現(xiàn)
Writer.prototype.render = function render (template, view, partials, config) {
var tags = this.getConfigTags(config);
var tokens = this.parse(template, tags);
var context = (view instanceof Context) ? view : new Context(view, undefined);
return this.renderTokens(tokens, context, partials, template, config);
};
render 函數(shù)調(diào)用 renderTokens 方法來解析,具體 renderTokens 方法的實(shí)現(xiàn),就不做深入的分析了。
一個(gè)案例切圖案例
需求是這樣的,后端使用費(fèi) Node.js 開發(fā),沒有 JS 運(yùn)行時(shí),為了能夠快速的完成項(xiàng)目,頁面的切頭由前端完成。此時(shí)頁面多,任務(wù)重,React/Vue 這種現(xiàn)代框架,需要服務(wù)端渲染,后端不想用 Node.js,增加復(fù)雜度。因?yàn)榍岸?Node.js 能夠使用模板渲染,并且模板種類很多,模板能夠解決復(fù)用的問題,所以前端功能化能夠解決,現(xiàn)代前端能結(jié)局的問題。
使用 exprss 服務(wù) + mustache 模板引擎為基礎(chǔ)實(shí)現(xiàn)一個(gè)簡單的切圖服務(wù)
- Express 創(chuàng)建服務(wù)和路由
- Nodemon 監(jiān)聽文件變化,重新啟動(dòng)路由
- esno + TypeScript + es Module 編寫服務(wù)端代碼
- prettier 格式化文件
在 express 中使用 mustache
import express from "express";
import mustacheExpress from "mustache-express";
app.engine("mustache", mustacheExpress());
app.set("view engine", "mustache");
app.set("views", toAbsolutePath("./views")); // 指定視圖路徑
- 渲染一個(gè)視圖
app.get(url, async (_, res) => {
res.render(url, data);
});
mustache 拆分模板的基本能用法
- 定義模板文件
- 引用模板文件,以及引入文件下的模板的方法
- 在模板中使用變量
- 條件判斷
- 列表渲染
mustache 官方 Github 倉庫,需要研究的可以自己訪問學(xué)習(xí),更多具體的用法。
示例
形成一個(gè)約定:因?yàn)橹蛔龊唵蔚那袌D工作,view + data 文件使用 render 函數(shù)渲染的時(shí)候一一對(duì)應(yīng),這樣就減少了很多的樣板代碼。 ·
- main.server.ts
讀取 views/ 文件夾下的所有視圖文件,布局文件不包含(簡化),將 /static 目錄設(shè)置為靜態(tài)文件夾目錄。路由不在單獨(dú)的寫了,此處統(tǒng)一處理為與視圖相同命名用于簡單的渲染。
// express
import express from "express";
import mustacheExpress from "mustache-express";
// config
import cutConfig from "./cut.config";
import defineVars from "iesmo";
// node
import { resolve } from "path";
import fs from "node:fs";
const { __dirname } = defineVars(import.meta);
export const toAbsolutePath = (p) => resolve(__dirname, p);
const routes = fs
.readdirSync(toAbsolutePath("./views/"))
.map((file) => {
if (!/\.mustache$/.test(file)) return null;
return file.replace(/\.mustache$/, "").toLowerCase();
})
.filter((i) => i !== null);
const app = express();
app.engine("mustache", mustacheExpress());
app.set("view engine", "mustache");
app.set("views", toAbsolutePath("./views"));
app.use("/static", express.static("static"));
routes.forEach((route) => {
let url = route === "index" ? "/" : `/${route}`;
app.get(url, async (_, res) => {
let data = (await import(`./data/${route}.ts`)).default;
res.render(route as string, data);
});
});
app.listen(cutConfig.port, () => {
console.log("server listening on port: ", cutConfig.port);
});
以 index.mustache 模板為示例:
數(shù)據(jù)存在 /data 文件夾下,默認(rèn)輸出一個(gè) JS 對(duì)象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{{title}}}</title>
{{#links}}
<link href="{{{href}}}" rel="external nofollow" rel="external nofollow" rel="stylesheet" />
{{/links}}
{{#scriptsHead}}
<script src="{{{src}}}"></script>
{{/scriptsHead}}
</head>
<body>
{{>tpls/list }}
{{>layout/footer}}
{{#scriptBody}}
<script src="{{{src}}}"></script>
{{/scriptBody}}
</body>
</html>
{{{title}}}插入數(shù)據(jù)- 根據(jù) html 渲染出數(shù)據(jù)
{{#links}}
<link href="{{{href}}}" rel="external nofollow" rel="external nofollow" rel="stylesheet" />
{{/links}}
- 使用文件夾中的模板
<body>
{{>tpls/list }}
{{>layout/footer}}
</body>
以上行為表示 tpls 目錄下的 list 模板文件和 layout 目錄下的 footer 模板文件
下面是一個(gè)具體的例子,使用到了 jQuery, Bootstrap 等等技術(shù)。可以自己嘗試一下,如果覺得還方便,可以給一個(gè)星星:
以上就是一文解析Express框架view對(duì)象使用的詳細(xì)內(nèi)容,更多關(guān)于Express框架view對(duì)象的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信小程序(應(yīng)用號(hào))開發(fā)新聞客戶端實(shí)例
這篇文章主要介紹了微信小程序(應(yīng)用號(hào))開發(fā)新聞客戶端實(shí)例的相關(guān)資料,需要的朋友可以參考下2016-10-10
詳解微信小程序 通過控制CSS實(shí)現(xiàn)view隱藏與顯示
這篇文章主要介紹了微信小程序 通過控制CSS實(shí)現(xiàn)view隱藏與顯示的相關(guān)資料,需要的朋友可以參考下2017-05-05
ECMAScript?6數(shù)組的擴(kuò)展實(shí)例詳解
這篇文章主要為大家介紹了ECMAScript?6數(shù)組的擴(kuò)展實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
You-Dont-Know-JS詞法作用域及兩種常見的模型學(xué)習(xí)文檔
這篇文章主要為大家介紹了JS?詞法作用域及兩種常見的模型詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
微信小程序中button組件的邊框設(shè)置的實(shí)例詳解
這篇文章主要介紹了微信小程序中button組件的邊框設(shè)置的實(shí)例詳解的相關(guān)資料,希望通過本文大家能夠掌握這部分內(nèi)容,需要的朋友可以參考下2017-09-09
TypeScript5.2引入新關(guān)鍵字using介紹
這篇文章主要介紹了TypeScript5.2引入新關(guān)鍵字using使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06

