Nodejs 如果不使用layout模板,则每个页面上内置的导航栏显示登陆名都必须在render里定义出来?
Nodejs 如果不使用layout模板,则每个页面上内置的导航栏显示登陆名都必须在render里定义出来?
/* GET home page. */ router.get(’/’, function (req, res) { res.render(‘index’, { title: ‘Express’, user: req.session.user }); });
/* GET 详细页面. */ router.get(’/thread’, function(req, res) { res.render(‘index’, { title: ‘Express’, user: req.session.user }); }); 每个页面都用<% include decorate/navbar.ejs %>定义了导航栏, 登录后,返回首页显示登陆名需render参数,链接到下个页面,也必须手工添加到render参数.岂不是很麻烦.有没有无需重复赋值的?
当然可以!如果你不想使用布局(layout)模板,但又希望避免在每个页面的渲染函数中重复定义相同的变量(例如 user
),你可以考虑通过中间件来统一处理这些共享的数据。这样你就可以在中间件中设置这些变量,然后在视图中直接使用它们。
以下是一个简单的例子来说明如何实现这一点:
示例代码
-
创建中间件
首先,你需要创建一个中间件来设置共享数据(如用户信息)。这个中间件可以在路由处理之前运行,并将用户信息添加到渲染上下文中。
// middleware.js const setUserContext = (req, res, next) => { if (req.session && req.session.user) { res.locals.user = req.session.user; } next(); }; module.exports = setUserContext;
-
在应用中使用中间件
在你的 Express 应用中引入并使用这个中间件。
// app.js const express = require('express'); const session = require('express-session'); const setUserContext = require('./middleware'); const app = express(); // 设置 session 中间件 app.use(session({ secret: 'your-secret-key', resave: false, saveUninitialized: true })); // 使用自定义中间件 app.use(setUserContext); // 定义路由 const router = express.Router(); router.get('/', function (req, res) { res.render('index', { title: 'Express' }); }); router.get('/thread', function (req, res) { res.render('thread', { title: 'Thread Detail' }); }); app.use('/', router); // 启动服务器 app.listen(3000, () => { console.log('Server is running on port 3000'); });
-
在视图中使用用户信息
在你的 EJS 视图文件中,你可以直接使用
user
变量,而不需要在每个路由处理函数中手动传递它。<!-- views/index.ejs --> <!DOCTYPE html> <html> <head> <title><%= title %></title> </head> <body> <nav> <% if (user) { %> <span>Welcome, <%= user.name %></span> <% } else { %> <a href="/login">Login</a> <% } %> </nav> <h1><%= title %></h1> </body> </html>
解释
-
中间件:通过创建一个中间件
setUserContext
,我们在每次请求时检查是否有用户会话信息,并将其存储在res.locals
对象中。res.locals
是一个对象,可以在所有视图中访问。 -
路由处理:在路由处理函数中,我们不再需要显式地传递
user
参数。由于中间件已经设置了user
,我们只需要传递其他特定于该页面的数据。 -
视图:在 EJS 模板中,我们可以直接使用
user
变量,而不需要在每个页面上重复传递它。
这种方法可以显著减少代码重复,提高可维护性。
通过静态/动态视图助手:
app.locals.title=‘bootrap3’; app.use(function(req, res, next) { res.locals.user=req.session.user; next(); });
在Node.js中,如果你不想使用layout模板,而希望避免在每个页面渲染时都手动传递用户信息,可以考虑将这些通用数据的处理封装在一个中间件或自定义函数中。这样,你就可以确保每次渲染页面时都能自动包含这些信息。
示例代码
中间件方法
- 创建一个中间件,用于设置全局变量,包括用户的登录名:
// middleware.js
function setGlobals(req, res, next) {
res.locals.user = req.session.user || null;
next();
}
module.exports = setGlobals;
- 在应用中使用该中间件:
const express = require('express');
const router = express.Router();
const setGlobals = require('./middleware');
app.use(setGlobals); // 应用全局中间件
router.get('/', function (req, res) {
res.render('index', { title: 'Express' });
});
router.get('/thread', function (req, res) {
res.render('index', { title: 'Express' });
});
- 在视图文件中使用
user
变量:
<!-- index.ejs -->
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<nav>
<% if (user) { %>
<span>Welcome, <%= user.name %></span>
<% } else { %>
<a href="/login">Login</a>
<% } %>
</nav>
<!-- 页面其他内容 -->
</body>
</html>
通过这种方式,无论哪个路由被访问,user
对象都会被自动添加到res.locals
中,因此在视图文件中可以直接使用它。
解释
res.locals
是一个对象,可以在所有路由处理程序中访问,并且会被传递给视图引擎。- 通过在中间件中设置
res.locals.user
,你确保了每次渲染页面时都能自动包含用户信息,从而避免了在每个路由处理程序中重复传递这些参数。
这种方法不仅简化了代码,还提高了代码的可维护性。