RuoYi-Vue 前后端分离架构下用户管理模块数据分页功能
📌 前言:在企业级后台管理系统中,数据分页是刚需中的刚需!当用户数据达到上千、上万条时,一次性加载所有数据会导致页面卡顿、网络拥堵、数据库压力暴增。今天就以 RuoYi-Vue(若依)框架为例,从前端到后端、从请求到渲染,手把手拆解用户管理模块分页功能的完整实现,新手也能轻松看懂~
💡 本文核心收获:掌握前后端分离分页的完整数据流、Vue分页组件配置、PageHelper插件原理、若依代码生成器模板用法,看完直接能套用在自己的项目/作业中!
很多新手做分页容易陷入“只看前端不看后端”“只写SQL不看插件”的误区,其实若依的分页是一个完整闭环,先记住这个流程图,后续拆解会更清晰:
🔄 完整链路:前端Vue页面(分页参数+组件)→ Axios请求(参数传递)→ 后端Controller(接收+开启分页)→ PageHelper插件(SQL改写)→ 数据库查询 → 后端封装结果 → 前端渲染(表格+分页条)
用通俗的话讲:前端告诉后端“我要第1页,每页10条数据”,后端接到请求后,自动处理分页逻辑,查完数据再告诉前端“总共有100条,这是第1页的10条”,前端再把数据展示出来。
二、前端代码剖析(分页的“发起者”)
前端核心是「传递分页参数、渲染分页组件、接收后端数据」,所有代码都在用户管理页面(index.vue)和相关工具类中,对应截图位置已标注,直接对照看即可。
2.1 Vue页面分页组件(最直观的分页入口)

核心代码(分页组件绑定):
|
html |
✨ 逐行解读:
- v-show="total > 0":没有数据时不显示分页条,避免空页面尴尬
- :total="total":绑定后端返回的总记录数,分页组件据此计算总页数
- :page.sync="queryParams.pageNum":双向绑定当前页码,用户点击翻页时,自动更新pageNum
- :limit.sync="queryParams.pageSize":双向绑定每页条数,默认10条/页,可手动修改
- @pagination="getList":翻页、改每页条数时,自动调用getList()方法重新加载数据
2.2 分页参数定义(前端告诉后端“怎么查”)

核心代码(queryParams对象):
|
javascript |
⚠️ 重点:pageNum和pageSize是分页的“灵魂参数”,必须和后端保持一致,否则分页会失效。
2.3 数据加载方法getList()(发起请求的核心)

核心代码(请求后端数据):
|
javascript |
💡 关键逻辑:
1. 页面初始化时(created钩子),会自动调用getList(),加载第一页数据;
2. 调用listUser() API,将queryParams(含分页参数)传给后端;
3. 接收后端返回的response,其中rows是当前页数据,total是总记录数。
2.4 API接口封装(统一请求路径)

核心代码(user.js中封装API):
|
javascript |
✅ 说明:这里的request是Axios实例,参数query会自动拼接到URL中,最终请求地址是:http://localhost/dev-api/system/user/list?pageNum=1&pageSize=10
2.5 Axios全局配置(请求的“基础设置”)

核心代码(request.js全局配置):
|
javascript |
⚠️ 注意:这个配置是所有前端请求的基础,分页请求也依赖它,不用单独修改,直接复用即可。
三、后端代码剖析(分页的“处理者”)
后端核心是「接收前端参数、开启分页、执行SQL、封装结果」,核心依赖MyBatis的PageHelper分页插件,不用手动写LIMIT,非常便捷。
3.1 Controller层分页接口(请求入口)

核心代码(SysUserController.java):
|
java |
✨ 核心方法解读:
- startPage():来自BaseController父类,作用是读取前端传递的pageNum和pageSize,告诉PageHelper插件“要分页”,自动拦截后续SQL。
- getDataTable(list):将查询到的list(当前页数据)封装成TableDataInfo对象,该对象包含rows(数据列表)和total(总记录数),正好对应前端需要的格式。
3.2 Controller类结构(接口基础)

核心代码(类定义):
|
java |
✅ 说明:@RequestMapping("/system/user") + @GetMapping("/list"),组成完整接口路径/system/user/list,和前端API的url完全对应。
3.3 Service层与Mapper层(执行查询)
Service层负责调用Mapper层执行SQL,本身不参与分页逻辑:
|
java |
Mapper层(SysUserMapper.xml)定义SQL,注意:没有手动写LIMIT:
|
xml |
⚠️ 关键:SQL的分页逻辑由PageHelper插件自动处理,我们只需要写“查询所有符合条件的数据”即可。

打开浏览器开发者工具(F12),切换到Network面板,刷新用户管理页面,就能看到分页请求的详细信息:
- 请求地址:http://localhost/dev-api/system/user/list?pageNum=1&pageSize=10
- 请求方法:GET
- 状态码:200 OK(请求成功)
- 响应数据:包含code(状态码)、msg(提示)、rows(当前页数据)、total(总记录数)
响应数据示例(简化版):
|
json |
✅ 验证要点:只要能看到pageNum、pageSize参数,且响应中有rows和total,说明分页请求正常。
五、分页原理讲解(PageHelper插件到底怎么工作?)
疑问:为什么不用写LIMIT,分页就能生效?核心就是PageHelper插件,它的工作原理很简单,就是「拦截SQL、自动改写」。
5.1 PageHelper核心工作流程
- 后端调用startPage()方法,PageHelper会从请求中读取pageNum和pageSize,存入线程变量;
- 当执行Mapper层的selectUserList()方法时,PageHelper拦截原始SQL;
- 自动生成两条SQL:① 统计总记录数(SELECT count(0) FROM ...);② 改写原始SQL,添加LIMIT子句;
- 执行两条SQL,将结果封装成Page对象,total来自count查询,rows来自LIMIT查询;
- getDataTable()方法从Page对象中提取rows和total,返回给前端。
5.2 分页参数与SQL转换示例
假设前端请求pageNum=2、pageSize=10:
- 计算偏移量:offset = (pageNum - 1) × pageSize = (2-1)×10 = 10;
- 原始SQL:SELECT ... FROM sys_user WHERE del_flag = '0';
- 改写后SQL(分页):SELECT ... FROM sys_user WHERE del_flag = '0' LIMIT 10, 10;
- 含义:从第11条数据开始,取10条(即第2页数据)。

若依框架最方便的就是代码生成器,分页接口不用手动写,模板自动生成,核心模板(controller.java.vm)如下:
|
velocity |
💡 模板逻辑:
1. 普通CRUD表(如sys_user):自动生成带startPage()和getDataTable()的分页接口;
2. 树形表(如部门表):生成不分页接口,直接返回所有数据;
3. 我们的用户管理模块是普通CRUD表,所以分页接口是模板自动生成的,直接复用即可。

用户管理页面运行效果如下,完美实现分页功能:
- 左侧:部门树形结构,可按部门筛选用户;
- 中间:用户表格,显示当前页数据(10条/页);
- 底部:分页组件,显示总记录数、当前页码、每页条数,支持翻页和页码跳转。
✅ 交互效果:点击“下一页”,前端自动更新pageNum=2,发起新请求,表格数据和分页条同步更新,整个过程无卡顿。
再梳理一遍完整闭环,加深记忆:
- 前端初始化:created钩子调用getList(),传递pageNum=1、pageSize=10;
- 发起请求:Axios携带参数,调用/list接口,请求头自动添加Token;
- 后端接收:Controller的list()方法调用startPage(),开启分页;
- SQL执行:PageHelper拦截SQL,自动生成count查询和LIMIT查询;
- 结果返回:Service调用Mapper查询,Controller封装rows和total,返回给前端;
- 前端渲染:将rows赋值给userList,total赋值给分页组件,完成页面展示。
|
层级 |
核心代码 |
作用 |
|
前端Vue |
queryParams、<pagination>组件 |
定义分页参数、渲染分页条 |
|
前端API |
listUser(query) |
封装分页请求 |
|
后端Controller |
startPage()、getDataTable() |
开启分页、封装结果 |
|
MyBatis |
PageHelper插件 |
自动改写SQL,添加LIMIT |
- 分页不生效:检查Controller是否调用startPage(),Mapper XML的SQL是否有语法错误;
- 总记录数不对:检查是否有数据权限过滤,或WHERE条件是否正确;
- 页码跳转异常:检查前端queryParams的pageNum是否双向绑定,@pagination事件是否绑定getList()。
以上就是RuoYi-Vue框架用户管理模块分页功能的完整剖析,从前端到后端、从原理到实战,覆盖了所有核心知识点。其实分页的本质就是“分段查询、按需加载”,若依已经帮我们封装好了大部分逻辑,我们只需要理解其流程,就能轻松复用和定制。
更多推荐

所有评论(0)