Node.js + Express分页实现:如何应用分页概念?每页展示4条数据
嘿,别着急,分页其实是Node.js+Express项目里超常见的需求,我来一步步帮你搞定每页4条数据的实现~
一、后端(Express)分页核心逻辑实现
分页的关键是通过页码参数计算需要跳过的数据条数,再配合固定的每页条数来查询对应数据。下面分两种常见数据库场景举例:
场景1:使用MongoDB + Mongoose
假设你的数据模型是Item,代码如下:
const Item = require('./models/Item'); // 处理分页数据请求的路由 app.get('/items', async (req, res) => { try { // 获取前端传递的页码,默认显示第1页 const currentPage = parseInt(req.query.page) || 1; // 固定每页展示4条数据 const pageSize = 4; // 计算需要跳过的数据条数:(当前页-1)*每页条数 const skipCount = (currentPage - 1) * pageSize; // 查询当前页的数据:跳过skipCount条,取pageSize条 const pageData = await Item.find().skip(skipCount).limit(pageSize); // 查询总数据条数,用来计算总页数 const totalItems = await Item.countDocuments(); const totalPages = Math.ceil(totalItems / pageSize); // 把分页相关数据传给前端模板 res.render('items', { data: pageData, currentPage, totalPages }); } catch (err) { console.error('分页查询出错:', err); res.status(500).send('服务器内部错误'); } });
场景2:使用MySQL(mysql2)
如果用关系型数据库,核心逻辑类似,只是查询语句换成LIMIT + OFFSET:
const mysql = require('mysql2/promise'); app.get('/items', async (req, res) => { const currentPage = parseInt(req.query.page) || 1; const pageSize = 4; const offset = (currentPage - 1) * pageSize; // 建立数据库连接 const connection = await mysql.createConnection({ host: 'localhost', user: 'your-user', password: 'your-password', database: 'your-db' }); try { // 查询当前页数据 const [pageData] = await connection.execute( 'SELECT * FROM items LIMIT ? OFFSET ?', [pageSize, offset] ); // 查询总数据条数 const [totalResult] = await connection.execute('SELECT COUNT(*) AS total FROM items'); const totalItems = totalResult[0].total; const totalPages = Math.ceil(totalItems / pageSize); res.render('items', { data: pageData, currentPage, totalPages }); } finally { await connection.end(); } });
二、前端页面调整(结合你的代码片段)
你的前端已经在循环渲染data了,现在需要加上分页导航栏,同时处理表单提交后的分页状态保留:
<!DOCTYPE html> <html> <head> <title>分页示例</title> <style> table { margin-top: 20px; border-collapse: collapse; width: 100%; } th, td { border: 1px solid #ddd; padding: 15px; text-align: left; } .pagination { margin-top: 20px; } .pagination a { margin: 0 5px; padding: 8px 16px; text-decoration: none; border: 1px solid #ddd; } .pagination a.active { background-color: #4CAF50; color: white; border: 1px solid #4CAF50; } </style> </head> <body> <form action="/deletechecks" method="post"> <!-- 隐藏字段:保留当前页码,提交后回到对应分页 --> <input type="hidden" name="page" value="<%= currentPage %>"> <table> <tr> <th>选择</th> <th>内容</th> <!-- 其他表头根据你的数据添加 --> </tr> <% for(var i = 0 ; i < data.length; i++) { %> <tr> <td><input type="checkbox" name="ids" value="<%= data[i]._id %>"></td> <td><%= data[i].content %></td> <!-- 其他数据列根据你的数据添加 --> </tr> <% } %> </table> <button type="submit">删除选中</button> </form> <!-- 分页导航组件 --> <div class="pagination"> <!-- 上一页按钮:当前页>1时显示 --> <% if(currentPage > 1) { %> <a href="/items?page=<%= currentPage - 1 %>">上一页</a> <% } %> <!-- 页码按钮:遍历总页数生成 --> <% for(let i = 1; i <= totalPages; i++) { %> <a href="/items?page=<%= i %>" <%= i === currentPage ? 'class="active"' : '' %>><%= i %></a> <% } %> <!-- 下一页按钮:当前页<总页数时显示 --> <% if(currentPage < totalPages) { %> <a href="/items?page=<%= currentPage + 1 %>">下一页</a> <% } %> </div> </body> </html>
三、表单提交后的分页状态处理
处理/deletechecks的POST路由时,要记得重定向回用户原来的分页:
app.post('/deletechecks', async (req, res) => { const { ids, page } = req.body; // 这里写你的删除逻辑,比如MongoDB的: // await Item.deleteMany({ _id: { $in: ids } }); // 重定向回对应分页,默认回到第1页 res.redirect(`/items?page=${page || 1}`); });
关键知识点小结
- 分页核心:通过
(当前页-1)*每页条数计算跳过的数据,配合limit获取当前页数据 - 总页数计算:用
Math.ceil(总数据数/每页条数),确保最后一页哪怕不足4条也能显示 - 前端交互:分页导航要正确传递
page参数,表单操作时用隐藏字段保留当前页码
这样应该就能完美实现你要的分页效果啦~
内容的提问来源于stack exchange,提问作者Shubham
相关产品推荐
相关产品推荐

