中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Express框架view對象如何使用

發布時間:2023-03-10 13:40:33 來源:億速云 閱讀:135 作者:iii 欄目:開發技術

本篇內容主要講解“Express框架view對象如何使用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Express框架view對象如何使用”吧!

    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 函數開始

    render 函數接收兩個參數,第一個 view 的路徑,第二個渲染數據。

    res.render = function render(view, options, callback) {
       // 調用 app.render
      app.render(view, opts, done);
    };

    下面是 app.render 代碼實現

    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 不在的情況下,會用 View 實例化 view, 最后調用 tryRender 函數,tryRender 函數會調用 view.render 方法:

    View 的實現

    module.exports = View;
    function View(name, options) {
      // store loaded engine
      this.engine = opts.engines[this.ext];
      // lookup path
      this.path = this.lookup(fileName);
    }

    跟一般的構造函數一樣,初始化一些屬性,用傳入的 opts 合并一些屬性。

    • View 擴展方法

    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 的具體實現就交給第三方引擎來實現了。

    mustache 的render 方法的實現

    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 函數調用 renderTokens 方法來解析,具體 renderTokens 方法的實現,就不做深入的分析了。

    一個案例切圖案例

    需求是這樣的,后端使用費 Node.js 開發,沒有 JS 運行時,為了能夠快速的完成項目,頁面的切頭由前端完成。此時頁面多,任務重,React/Vue 這種現代框架,需要服務端渲染,后端不想用 Node.js,增加復雜度。因為前端 Node.js 能夠使用模板渲染,并且模板種類很多,模板能夠解決復用的問題,所以前端功能化能夠解決,現代前端能結局的問題。

    使用 exprss 服務 + mustache 模板引擎為基礎實現一個簡單的切圖服務

    • Express 創建服務和路由

    • Nodemon 監聽文件變化,重新啟動路由

    • esno + TypeScript + es Module 編寫服務端代碼

    • 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")); // 指定視圖路徑
    • 渲染一個視圖

    app.get(url, async (_, res) => {
        res.render(url, data);
    });

    mustache 拆分模板的基本能用法

    • 定義模板文件

    • 引用模板文件,以及引入文件下的模板的方法

    • 在模板中使用變量

    • 條件判斷

    • 列表渲染

    mustache 官方 Github 倉庫,需要研究的可以自己訪問學習,更多具體的用法。

    示例

    形成一個約定:因為只做簡單的切圖工作,view + data 文件使用 render 函數渲染的時候一一對應,這樣就減少了很多的樣板代碼。 ·

    • main.server.ts

    讀取 views/ 文件夾下的所有視圖文件,布局文件不包含(簡化),將 /static 目錄設置為靜態文件夾目錄。路由不在單獨的寫了,此處統一處理為與視圖相同命名用于簡單的渲染。

    // 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 模板為示例:

    數據存在 /data 文件夾下,默認輸出一個 JS 對象

    <!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}}} 插入數據

    • 根據 html 渲染出數據

    {{#links}}
    <link href="{{{href}}}" rel="external nofollow"  rel="external nofollow"  rel="stylesheet" />
    {{/links}}
    • 使用文件夾中的模板

    <body>
        {{>tpls/list }}
        {{>layout/footer}}
      </body>

    以上行為表示 tpls 目錄下的 list 模板文件和 layout 目錄下的 footer 模板文件

    到此,相信大家對“Express框架view對象如何使用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    朝阳市| 大兴区| 垫江县| 沙田区| 外汇| 枝江市| 泰和县| 海城市| 白河县| 海丰县| 曲阳县| 皋兰县| 甘孜县| 黄陵县| 额尔古纳市| 灯塔市| 蓬安县| 台北县| 富锦市| 云梦县| 舞钢市| 安顺市| 饶平县| 江北区| 改则县| 喜德县| 桐柏县| 淮北市| 突泉县| 宜兰市| 岳池县| 许昌市| 闸北区| 曲水县| 淮滨县| 大埔区| 逊克县| 安岳县| 隆尧县| 铜山县| 临沂市|