【10分钟系列】手把手带你打造极致用户体验的Pagination组件

924 阅读3分钟

前言

开发中,经常有Element UI的表格组件、分页组件搭配使用的场景。

分页组件封装得确实强大,但是在CRUD的业务中,分页组件由于某些限制,明显降低了用户体验。

例如:删除本页最后一条数据后,表格停留在NoData状态

因此,本文总结常见“Bug”,并提供了完美的解决方案。今后遇到,立马掏出本方案,愉快的贴上去吧

举个例子,类似以下这种极为常见的后台管理页面:

002.png

分页组件的属性及方法

这是分页组件的完整功能:

112.png

 <el-pagination
    background
    layout="total, sizes, prev, pager, next, jumper"
    :page-size="queryParams.size"
    :current-page="queryParams.page"
    :page-sizes="[2, 5, 10, 15]"
    :total="totalItems"
    @size-change="sizeChangeHandler"
    @current-change="currentChangeHandler"
  />
export default {
  data() {
    return {
      // 表格组件的依赖数组
      tableList: [],

      totalItems: 0,
      // 翻页的查询参数
      queryParams: {
        size: 5, // 每页的容量大小
        page: 1 // 当前在多少页
      }
    }
  }
  • layout属性:分页组件的布局,通过改变total, sizes, prev, pager, next, jumper字符的顺序,就能修改它们在页面中的相对位置。它们依次表示后端数据总条数、页面容量、上一页、可选页码及当前页码、下一页、跳转到某页
  • background属性:为 prev, pager, next 都加上背景色
  • page-size属性:当前的页面容量,即此刻页面显示多少条数据,依赖数据是queryParams.size
  • current-page属性:当前在哪一页,依赖数据是queryParams.page
  • page-sizes属性:写死的数组,数组成员可直接覆盖queryParams.size
  • total属性:后端数据总条数,依赖数据是totalItems
  • size-change事件:当页面容量改变时,自动触发,改变后的页面容量会作为参数传入sizeChangeHandler回调。
  • current-change事件:当前页码改变时,自动触发,改变后的页码会作为参数传入currentChangeHandler回调。

分页组件的深入理解详见我的文章:juejin.cn/post/705120…

问题

问题1

描述:当你在表格最后一页,并且删除此时最后一条数据后,表单显示“ 暂无数据 ”,并没有将页面切回有数据的上一页 220.png 解决方案:删除表格数据时,动态检测是否为最后一条数据,并自动跳转到上一页

    // 删除角色,rowId是使用插槽拿到的当前行表格的数据
    delRoleHandler(rowId) {
      // 弹框询问
      this.$confirm('此操作将永久删除, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
      // 点击确认进then
        .then(async() => {
          // 1.发删除的请求
          await delRoleApi(rowId)
          /** ***
          *---错误点(页面组件已知bug):
              如果当前页被你删得只剩一条数据时,假设你删掉最后一条,那么页面就会显示No Data,要避免这种bug
          *---解决思路:
              自动向前翻一页,将减1的page值作为这种情况下的请求值发给后端,再发请求时就能获取前一页的数据,并渲染到页面上
          */
          // 判断当前表格依赖的tableData数组是否只剩一条数据
          if (this.tableList.length === 1) {
            // 如果是,令这次请求的页码自动向前减1;但是要防止当前页只有1页
            this.queryParams.page--
            if (this.queryParams.page < 0) {
              this.queryParams.page = 1
            }
          }
          // 2.成功提醒
          this.$message({ type: 'success', message: '删除成功!' })
          // 3. 刷新页面
          this.getRoleList()
        })
        // 点击取消进catch
        .catch(e => e)

问题2

描述:修改页面容量后,页面没有回到其实第一页

解决方案:触发size-change事件后,强制跳转到第1页

// 页面容量改变时的回调
    handleSizeChange(val) {
      // 1. 组件能自动获取当前的页面容量-pagesize,将新值覆盖queryParams变量中的旧值
      this.queryParams.size = val
      // 2.切换页面容量后,默认回到第 1 页
      this.queryParams.page = 1
      // 3. 根据最新size再发请求,更新页面
      this.getRoleList()
    },

问题3

描述:添加数据后,表格当前页未显示刚刚添加的数据

解决方案1:如果后端设定的是将最新数据添加到所有数据的尾部,你应该在添加成功后触发刷新函数时强制跳到最后一页

refreshPageHandler() {
      // 新加一条数据后,后端那里的数据一定增加1
      this.total = this.total + 1
      // 最新页就是最后一页,最后一页等于数据总条数 除 当前设定的每页数据容量
      this.queryParams.page = Math.ceil(this.totalItems / this.queryParams.size)
      // 依据最新的 page 和 size 再发请求
      this.getRoleList()
    },

解决方案2:如果后端设定的是将最新数据添加到所有数据的头部,你应该在添加成功后触发刷新函数时强制跳到第一页

refreshPageHandler() {
      // 手动指定为第1页
      this.queryParams.page = 1
      // 依据最新的 page 和 size 再发请求
      this.getRoleList()
    },