Express框架view对象如何使用

其他教程   发布日期:2023年08月16日   浏览次数:372

本篇内容主要讲解“Express框架view对象如何使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Express框架view对象如何使用”吧!

    Expess View 从指定渲染引擎开始

    以 mustache 渲染引擎为例,需要初始化一些代码

    1. const app = express()
    2. app.set("view engine", "mustache");
    3. app.engine("mustache", mustacheExpress());
    4. app.set("views", toAbsolutePath("./views"));
    • 指定视图引擎

    • 指定引擎工具

    • 指定视图位置

    安装依赖

    1. pnpm install mustache mustache-express

    从 res.render 函数开始

    render 函数接收两个参数,第一个 view 的路径,第二个渲染数据。

    1. res.render = function render(view, options, callback) {
    2. // 调用 app.render
    3. app.render(view, opts, done);
    4. };

    下面是 app.render 代码实现

    1. app.render = function render(name, options, callback) {
    2. // view
    3. if (!view) {
    4. var View = this.get('view');
    5. view = new View(name, {
    6. defaultEngine: this.get('view engine'),
    7. root: this.get('views'),
    8. engines: engines
    9. });
    10. if (!view.path) {
    11. var dirs = Array.isArray(view.root) && view.root.length > 1
    12. ? 'directories "' + view.root.slice(0, -1).join('", "') + '" or "' + view.root[view.root.length - 1] + '"'
    13. : 'directory "' + view.root + '"'
    14. var err = new Error('Failed to lookup view "' + name + '" in views ' + dirs);
    15. err.view = view;
    16. return done(err);
    17. }
    18. // prime the cache
    19. if (renderOptions.cache) {
    20. cache[name] = view;
    21. }
    22. }
    23. // render
    24. tryRender(view, renderOptions, done);
    25. };

    在 view 不在的情况下,会用 View 实例化 view, 最后调用 tryRender 函数,tryRender 函数会调用 view.render 方法:

    View 的实现

    1. module.exports = View;
    2. function View(name, options) {
    3. // store loaded engine
    4. this.engine = opts.engines[this.ext];
    5. // lookup path
    6. this.path = this.lookup(fileName);
    7. }

    跟一般的构造函数一样,初始化一些属性,用传入的 opts 合并一些属性。

    • View 扩展方法

    1. View.prototype.lookup = function lookup(name) {}
    2. View.prototype.render = function render(options, callback) {
    3. this.engine(this.path, options, callback);
    4. }
    5. View.prototype.resolve = function resolve(dir, file) {}

    render 的具体实现就交给第三方引擎来实现了。

    mustache 的render 方法的实现

    1. Writer.prototype.render = function render (template, view, partials, config) {
    2. var tags = this.getConfigTags(config);
    3. var tokens = this.parse(template, tags);
    4. var context = (view instanceof Context) ? view : new Context(view, undefined);
    5. return this.renderTokens(tokens, context, partials, template, config);
    6. };

    render 函数调用 renderTokens 方法来解析,具体 renderTokens 方法的实现,就不做深入的分析了。

    一个案例切图案例

    需求是这样的,后端使用费 Node.js 开发,没有 JS 运行时,为了能够快速的完成项目,页面的切头由前端完成。此时页面多,任务重,React/Vue 这种现代框架,需要服务端渲染,后端不想用 Node.js,增加复杂度。因为前端 Node.js 能够使用模板渲染,并且模板种类很多,模板能够解决复用的问题,所以前端功能化能够解决,现代前端能结局的问题。

    使用 exprss 服务 + mustache 模板引擎为基础实现一个简单的切图服务

    • Express 创建服务和路由

    • Nodemon 监听文件变化,重新启动路由

    • esno + TypeScript + es Module 编写服务端代码

    • prettier 格式化文件

    在 express 中使用 mustache

    1. import express from "express";
    2. import mustacheExpress from "mustache-express";
    3. app.engine("mustache", mustacheExpress());
    4. app.set("view engine", "mustache");
    5. app.set("views", toAbsolutePath("./views")); // 指定视图路径
    • 渲染一个视图

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

    mustache 拆分模板的基本能用法

    • 定义模板文件

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

    • 在模板中使用变量

    • 条件判断

    • 列表渲染

    mustache 官方 Github 仓库,需要研究的可以自己访问学习,更多具体的用法。

    示例

    形成一个约定:因为只做简单的切图工作,view + data 文件使用 render 函数渲染的时候一一对应,这样就减少了很多的样板代码。 ·

    • main.server.ts

    读取

    1. views/
    文件夹下的所有视图文件,布局文件不包含(简化),将
    1. /static
    目录设置为静态文件夹目录。路由不在单独的写了,此处统一处理为与视图相同命名用于简单的渲染。
    1. // express
    2. import express from "express";
    3. import mustacheExpress from "mustache-express";
    4. // config
    5. import cutConfig from "./cut.config";
    6. import defineVars from "iesmo";
    7. // node
    8. import { resolve } from "path";
    9. import fs from "node:fs";
    10. const { __dirname } = defineVars(import.meta);
    11. export const toAbsolutePath = (p) => resolve(__dirname, p);
    12. const routes = fs
    13. .readdirSync(toAbsolutePath("./views/"))
    14. .map((file) => {
    15. if (!/.mustache$/.test(file)) return null;
    16. return file.replace(/.mustache$/, "").toLowerCase();
    17. })
    18. .filter((i) => i !== null);
    19. const app = express();
    20. app.engine("mustache", mustacheExpress());
    21. app.set("view engine", "mustache");
    22. app.set("views", toAbsolutePath("./views"));
    23. app.use("/static", express.static("static"));
    24. routes.forEach((route) => {
    25. let url = route === "index" ? "/" : `/${route}`;
    26. app.get(url, async (_, res) => {
    27. let data = (await import(`./data/${route}.ts`)).default;
    28. res.render(route as string, data);
    29. });
    30. });
    31. app.listen(cutConfig.port, () => {
    32. console.log("server listening on port: ", cutConfig.port);
    33. });

    以 index.mustache 模板为示例:

    数据存在

    1. /data
    文件夹下,默认输出一个 JS 对象
    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8" />
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    7. <title>{{{title}}}</title>
    8. {{#links}}
    9. <link href="https://www.19jp.com">
      1. {{{title}}}
      插入数据
    • 根据 html 渲染出数据

    1. {{#links}}
    2. <link href="https://www.19jp.com">
    • 使用文件夹中的模板

    1. <body>
    2. {{>tpls/list }}
    3. {{>layout/footer}}
    4. </body>

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

    以上就是Express框架view对象如何使用的详细内容,更多关于Express框架view对象如何使用的资料请关注九品源码其它相关文章!