Nodejs express局部渲染

Nodejs express局部渲染

我们一般吧header footer都包起来,index.ejs里面会有 <%include header.ejs %> 直接引入 如果header里面有需要数据库的数据渲染 每次app.get(’/’, routes.index);或者其他页面都需要 res.render(‘index’,{‘header’ : results,‘nav’ : results2}); 重复每次读取header里面的数据 这个怎么能解决?能不能分开?

3 回复

当然可以解决这个问题。在使用 Express 和 EJS 模板引擎时,我们可以利用局部模板(partial templates)来避免重复渲染相同的头部或尾部内容。局部模板允许我们在多个视图中重用相同的 HTML 片段,这样就可以减少代码冗余并提高效率。

示例代码

假设我们有以下目录结构:

/views
  /partials
    header.ejs
    footer.ejs
  index.ejs
/routes
  index.js

views/partials/header.ejs

<header>
  <h1>Welcome to My Website</h1>
  <% if (user) { %>
    <p>Hello, <%= user.name %>!</p>
  <% } else { %>
    <p>Please log in.</p>
  <% } %>
</header>

views/index.ejs

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Home Page</title>
</head>
<body>
  <!-- 引入局部模板 -->
  <%- include('partials/header'); %>

  <main>
    <h2>Welcome to the Home Page</h2>
    <!-- 其他页面内容 -->
  </main>

  <!-- 引入局部模板 -->
  <%- include('partials/footer'); %>
</body>
</html>

routes/index.js

const express = require('express');
const router = express.Router();
const db = require('../models/db'); // 假设你有一个数据库模块

// 渲染主页
router.get('/', async (req, res) => {
  try {
    const results = await db.query('SELECT * FROM some_table WHERE condition');
    const results2 = await db.query('SELECT * FROM another_table WHERE condition');
    res.render('index', { 
      header: results,
      nav: results2,
      user: req.user // 假设用户信息已经通过中间件设置
    });
  } catch (error) {
    console.error(error);
    res.status(500).send('Internal Server Error');
  }
});

module.exports = router;

解释

  1. 局部模板header.ejsfooter.ejs 被放在 views/partials 文件夹中。这些文件包含重复的 HTML 代码片段。

  2. 主视图文件index.ejs 中使用 <%- include('partials/header'); %> 来引入局部模板。这样,每次渲染 index.ejs 时,都会自动包含 header.ejs 的内容。

  3. 数据传递:在路由处理函数中,我们查询数据库并将结果传递给视图。这些数据可以在局部模板中使用,而不需要在每个页面中重复调用数据库。

通过这种方式,你可以有效地管理和重用代码,同时保持代码的整洁和高效。


只用浏览器端模板knockout.js的路过

在使用 Express 和 EJS 模板引擎时,为了提高性能和代码复用性,可以将 headerfooter 等局部视图单独渲染,并通过局部变量的方式传递数据。这样可以避免在每次渲染页面时重复读取相同的数据。

解决方案

  1. 创建局部视图

    • header.ejs 视为一个局部视图。
  2. 使用局部变量

    • 在渲染主视图(如 index.ejs)时,只传递一次数据库查询结果。
  3. 优化路由处理函数

    • 使用中间件来提前获取数据,然后将这些数据传递给所有后续的渲染操作。

示例代码

假设我们有一个数据库查询函数 getHeaderData,用于获取 header 的数据。

// 获取 header 数据的函数
const getHeaderData = async (req, res, next) => {
  try {
    const headerData = await fetchHeaderDataFromDatabase();
    req.headerData = headerData;
    next();
  } catch (error) {
    console.error('Error fetching header data:', error);
    next(error);
  }
};

// 路由处理函数
app.get('/', getHeaderData, (req, res) => {
  res.render('index', { nav: req.navData });
});

// 在 index.ejs 中引用 header.ejs
<%- include('header.ejs', { headerData: headerData }) %>

具体步骤

  1. 定义中间件

    • 创建一个中间件 getHeaderData,用于获取 header 数据并将其附加到请求对象上。
  2. 路由处理

    • 在路由处理函数中使用这个中间件,确保在渲染 index 页面之前已经获取了 header 数据。
  3. EJS 渲染

    • index.ejs 中使用 <%- include('header.ejs', { headerData: headerData }) %> 包含局部视图,并传递局部变量。

这样,header 数据只需查询一次,而不是在每次渲染页面时都重新查询。这不仅提高了性能,还使代码更加清晰和易于维护。

回到顶部