ruoyi若依框架分页功能实现分析

本文详细分析了若依框架下的前端如何通过js处理分页请求,以及后端如何通过PageHelper插件实现分页逻辑,以系统用户页面为例,包括前端查询参数扩展和后端权限验证与数据查询过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

系列文章

ruoyi若依框架学习笔记-01

ruoyi若依框架分页功能实现分析

ruoyi若依框架SpringSecurity实现分析

概要

今天来分析一下若依前后端分离版本的分页功能的实现,以系统用户页面为例,从前后端一一分析。

前端分析

在这里插入图片描述
我把相关的js代码拿出来放到一起,total即分页数据的总数,和total绑定,page即页号,limit即页面数据大小限制,都和queryParms绑定。

data(){
 return{
	  // 遮罩层
      loading: true,
 	  // 总条数
      total: 0,
	  // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        userName: undefined,
        phonenumber: undefined,
        status: undefined,
        deptId: undefined
      },
      // 日期范围
      dateRange: [],
 }
},
created() {
    this.getList();
    //下面的先不看
    //this.getDeptTree();
    //this.getConfigKey("sys.user.initPassword").then(response => {
    //  this.initPassword = response.msg;
    //});
  },
  methods: {
    /** 查询用户列表 */
    getList() {
	  //loading这个参数为true则说明还在等待后端响应阶段
      this.loading = true;
      listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
      	  //当后端响应成功将数据赋值给userList,进行页面渲染
          this.userList = response.rows;
          this.total = response.total;
          this.loading = false;
        }
      );
    },
    }

我们从前端发送一个所有查询数据都不为空的分页请求:
在这里插入图片描述
可以看到除了queryParams对象中的内容,还有两个属性:

params[beginTime]: 2024-01-19
params[endTime]: 2024-02-02

其实这是在src/utils/ruoyi.js中有暴露一个方法生成的,该方法的作用就是为表单对象添加日期范围,因为前端中有个表单项是按照时间间隔查询的,他的绑定属性是dateRange,是一个数组[],数组中的第一项是起始时间,第二项是终止时间

// 添加日期范围
export function addDateRange(params, dateRange, propName) {
  let search = params;
  search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {};
  dateRange = Array.isArray(dateRange) ? dateRange : [];
  if (typeof (propName) === 'undefined') {
    search.params['beginTime'] = dateRange[0];
    search.params['endTime'] = dateRange[1];
  } else {
    search.params['begin' + propName] = dateRange[0];
    search.params['end' + propName] = dateRange[1];
  }
  return search;
}

后端分析

对于后端分析,第一步就是找接口,
在这里插入图片描述
通过前端请求,我们可以知道后端接口请求路径是/system/user/list,可以使用idea插件RestfulTool来找到接口地址
在这里插入图片描述
非常的方便。来分析一下后端接口:

/**
     * 获取用户列表
     */
     //这个注解就是验证访问这个接口的用户是否有对应的权限
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysUser user)
    {
        startPage();
        List<SysUser> list = userService.selectUserList(user);
        return getDataTable(list);
    }

从ruoyi的pom文件中就能知道他使用的是github的pageHelper插件。与直接使用不同,我们来看一下ruoyi是怎么封装的。
首先,这个startPage()方法来自SysUserController的父类BaseController,

/**
     * 设置请求分页数据
     */
    protected void startPage()
    {
        PageUtils.startPage();
    }

看得出来,他是通过PageUtils工具类的startPage()方法实现的。这个类继承自PageHelper类

public class PageUtils extends PageHelper
{
    /**
     * 设置请求分页数据
     */
    public static void startPage()
    {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
        Boolean reasonable = pageDomain.getReasonable();
        PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
    }

    /**
     * 清理分页的线程变量
     */
    public static void clearPage()
    {
        PageHelper.clearPage();
    }
}

来分析一下方法的内部:
第一步便是调用了TableSupport.buildPageRequest()拿到了一个对象domain,从方法的下面该对象的属性,我们就能看出他是封装分页参数的,
但是还是去看一下这个方法:

PageDomain pageDomain = new PageDomain();
        pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1));
        pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10));
        pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN));
        pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC));
        pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE));
        return pageDomain;

不用看都知道ServletUtils.getParameter是拿到请求参数的,ServletUtils这个类就不深入分析了。
所以这个方法就是赋值的一个操作。

PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);

这段代码中前面的一个方法好理解,是PageHeper的最基本分页的一个方法,他后面的setReasonable(reasonable)方法,这个其实就是对参数进行逻辑处理。
比如:前端传递的参数是:pageNum=-1这肯定是不行的吧,页号肯定不能为负数吧!
再后面

List<SysUser> list = userService.selectUserList(user);

从数据库中根据分页参数拿到相应的数据。
最后将数据封装成前端想要的样子就行了~

/**
     * 响应请求分页数据
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected TableDataInfo getDataTable(List<?> list)
    {
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(list);
        rspData.setTotal(new PageInfo(list).getTotal());
        return rspData;
    }
### 若依前端框架分页固定的实现方法 在若依前端框架中,为了实现在表格组件中的分页功能并保持页面刷新时不丢失当前页码,通常会通过保存用户的分页状态来达到这一目的。具体来说,在用户切换到某一页时,可以将该页的信息存储起来;当页面重新加载或跳转回来时读取这些信息以恢复之前的浏览位置。 对于Vue版本的RuoYi项目而言,可以通过`vuex`持久化插件[vuex-persistedstate][^1] 来帮助管理这种跨会话的数据共享需求。下面是一个简单的例子展示如何设置以及应用此特性: #### 安装依赖库 首先安装必要的npm包: ```bash npm install vuex-persistedstate --save ``` #### 修改store/index.js文件 接着修改Vuex store的相关部分以便于支持数据持久化操作: ```javascript import Vue from 'vue' import Vuex from 'vuex' import createPersistedState from "vuex-persistedstate"; Vue.use(Vuex) const store = new Vuex.Store({ state: { paginationInfo: {} // 存储分页信息的对象 }, mutations: { SET_PAGINATION_INFO(state, info){ Object.assign(state.paginationInfo,info); } }, plugins: [ createPersistedState() ] }) export default store; ``` #### 组件内使用 最后,在实际使用的Table组件或者其他涉及到分页逻辑的地方更新代码如下所示: ```html <template> <div class="app-container"> <!-- 表格 --> <el-table :data="tableData.slice((currentPage-1)*pageSize, currentPage*pageSize)"> ... </el-table> <!-- 分页器 --> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :page-size.sync="pagination.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total"> </el-pagination> </div> </template> <script> ... computed:{ ...mapState(['paginationInfo']), }, methods: { handleSizeChange(val) { this.$set(this.pagination,'pageSize', val); const pageInfo={...this.pagination}; this.SET_PAGINATION_INFO(pageInfo); }, handleCurrentChange(val) { this.$set(this.pagination,'currentPage',val); const pageInfo={...this.pagination}; this.SET_PAGINATION_INFO(pageInfo); } } </script> ``` 上述代码片段展示了怎样利用Vuex的状态管理和持久化机制来记录和重现分页参数[^2]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gunalaer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值