分页组件遇到的一些问题

563 阅读4分钟

1.分页组件,如果删除最后一页的数据 页面会有bug,整个页面没有数据了 想要的效果是本页信息删完后 页面显示的是前一页的信息数据(不要页面总删除本页信息后显示第一页信息)

image.png

解决办法:在删除成功之,去检测一下,是否当前删除的是当前页最后一条数据,如果是,就把页码-1,再发请求

image.png

2.分页组件 添加新元素之后页码没动 现在要做的就是判断信息鞥的元素应该显示到哪一页,取出这一页的信息,这可以设置通过代码的形式更新页码 有一个属性页面属性可以满足需要 :current-page.sync="curPage" 在data中定义 curPage ,这个curPage就是当前要跳转的页面

image.png

同步设curPage

async loadRoles() {
      try {
        // page, pageSize
        const res = await getRoles(this.pageParams.page, this.pageParams.pageSize)
        console.log(res)
        this.roles = res.data.rows
        this.total = res.data.total

+      this.curPage = this.pageParams.page
      } catch (err) {
        console.log(err)
      }
    }

补充计算属性

computed: {
    // 表格中最大的页码
    maxNum() {
      return Math.ceil(this.total / this.pageParams.pageSize)
    },
    // 最后一页是不是满的
    isLastPageFulled: function() {
      return this.total % this.pageParams.pageSize === 0
    }
  }

修改doAdd()

async doAdd() {
      try {
        // 1. 调用接口
        const res = await addRole(this.form)
        // 2. 关闭弹层
        this.showDialog = false
        // if(表格的最后一页是满) {
        //   想查看最新添加的数据,要跳到最大页码的下一页
        //  }
        if (this.isLastPageFulled) {
          this.pageParams.page = this.maxNum + 1
        } else {
          // 想查看最新添加的数据,要跳到最大页码
          this.pageParams.page = this.maxNum
        }
        // if (this.isLastPage && this.roles.length === this.pageParams.pageSize) {
        //   this.pageParams.page++
        //   // 页码++
        // }
        // 3. 重发请求
        this.loadRoles()
        console.log(res)
      } catch (err) {
        console.log(err)
      }
    }

3.数据回填出现的一个问题 回填时候直接用对象的引用赋值 导致表单数据与弹框数据始终一致 当弹框点击取消时 表单数据并没有更改为之前数据 这时候就又用到浅拷贝 用浅拷贝的数据去赋值更改避免使用同一个栈区地址

image.png

4.弹框关闭重置数据 现在的表单直接是弄到弹框里 之前是弄一个新的组件,涉及到不同组件间的切换 用那四种方式都可以 现在是就在一个组件之间 不涉及created mounted等,所以现在的问题是当开始时,forDate的数据是空的,但是当点击编辑时,forDate已经有了新的数据,而对于对话框来说,它隐藏时,其中的表单数据并不会重置:因为组件本身并没有销毁和重建;所以需要自己写逻辑代码去把forDate里的数据清空,这样每次都是初始状态.

image.png

image.png

因为只有绑定了表单验证的数据才能被.resetFields()清空 所以还可以单个赋值把没有绑定表单验证的数据也进行清空

image.png

5.关于自定义作用域 插槽的说明

image.png

image.png

6.如何设置公共组件

image.png

7. 自己封装一个分页居中的函数

当一个项目中有许多数据需要展示的时候,众所周知一个页面是没有办法放下所有数据的,所以会出现分页的需求。那么分页又会产生什么新的需求呢?如果你也有这样的疑问,那就看看本文内容哦~

那么如果分页特别多的时候,我们也不能把所有页码都展示出来,这时候就需要动态的展示当前选中页左右几个就可以了,为了用户更好的体验,尽量让选中的页码居中显示,这样也是极好的。

在可能的情况下,让选中的页码值,在中间显示。

// total: 总条数
// size: 每页几条
// page: 当前第几页
// btnCount: 最多能看到几个按钮

function(){
	const arr = [] //能看到的页码集合
	
	return arr
}

// 在可能的情况下,让page处于正中间
      // f(100, 10, 3, 5) // ==> [1, 2, 3, 4, 5]
      // f(100, 10, 7, 5) // ==> [5, 6, 7, 8, 9]
      // f(100, 10, 2, 5) // ==> [1, 2, 3, 4, 5]
      // f(100, 10, 5, 5) // ==> [3, 4, 5, 6, 7]
复制代码

代码演示

当要展示的页码数组为奇数的时候,才能实现选中页码在中间显示。 代码如下(示例):

 function f(total, size, page, btnCount = 5) {
        // show me your code
        const arr = [] // 能看到的页码集合
        let num = Math.floor(btnCount / 2)

        let totalPage = Math.ceil(total / size) // 拿到总条数
        let leftPage = page - num // 拿到起始数字
        let rightPage = page + num // 拿到结尾数字

        // 判断要展示页码数是否为偶数或者大于总页码数,或者要查看的当前页大于总页码
        if (btnCount % 2 === 0 || btnCount > totalPage || page > totalPage) {
          alert('请检查输入数字是否为奇数或者输入数字大于总页数')
          return
        }

        // 判断左侧数字是否小于等于1
        if (leftPage <= 1) {
          // 从1开始循环到默认要展示的页码数为止
          for (let i = 1; i <= btnCount; i++) {
            arr.push(i)
          }
        } else if (rightPage > totalPage) {
          // 判断右边的数字是否大于总页码数
          // 计算得到左侧起始值,循环到总页码数为止
          for (let i = totalPage - btnCount + 1; i <= totalPage; i++) {
            arr.push(i)
          }
        } else {
          // 左右的数字均在总页码数的安全范围内
          for (let i = leftPage; i <= rightPage; i++) {
            arr.push(i)
          }
        }
        return arr
      }

结果展示

为了让大家更直观的看到效果,这里写了一个html页面,模拟了一下分页页面。 代码如下(示例):

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      div {
        margin: 50px auto;
        width: 500px;
        height: 30px;
      }

      .paging {
        display: flex;
        justify-content: center;
      }

      ul {
        list-style: none;
      }

      li {
        float: left;
        width: 30px;
        height: 30px;
        line-height: 30px;
        text-align: center;
        border: 1px solid #ccc;
      }
    </style>
  </head>
  <body>
    <div class="form">
      <form action="">
        <select name="total" id="">
          <option value="100">共100条</option>
          <option value="200">共200条</option>
        </select>
        <select name="size" id="">
          <option value="10">10/页</option>
          <option value="20">20/页</option>
          <option value="30">30/页</option>
          <option value="40">40/页</option>
        </select>
        <input type="number" name="page" placeholder="请输入要查看第几页" />
        <input type="number" name="btnCount" value="5" placeholder="请输入默认展示几条数据" />
        <button>确定</button>
      </form>
    </div>
    <div class="paging">
      <ul></ul>
    </div>

    <script src="jquery-3.5.1.min.js"></script>
    <!-- 引入封装好的分页js -->
    <script src="./paging.js"></script>
    <script>
      $('form').on('submit', function (e) {
        // 每一次提交表单,先将ul内的内容清空一次
        $('ul').html('')
        e.preventDefault()
        // 拿到填写的表单数据
        let fd = new FormData(this)
        let total = +fd.get('total')
        let size = +fd.get('size')
        let page = +fd.get('page')
        let btnCount = +fd.get('btnCount')

        let arr = f(total, size, page, btnCount)
        // 循环数组,将li追加到ul中
        arr.forEach(item => {
          $('ul').append(`<li>${item}</li>`)
        })

        // 拿到当前要查看的页码在数组中的索引值,给对应的li给背景色
        let index = arr.findIndex(item => item === page)
        $('li').eq(index).css('backgroundColor', 'skyblue')
      })
    </script>
  </body>
</html>
复制代码

运行后的结果如下: 在这里插入图片描述 在这里插入图片描述

在这里插入图片描述