前端分页的实现

前言

这两天写了一个个人项目-留言墙:一个以在线便利签的形式,也可以扩展成许愿墙、树洞的一个项目。上篇文章地址链接:留言墙

起先功能点很少,后面慢慢加入了一些留言总的建议性改造或者优化。比如:

  • 增加字体和标题颜色
  • 增加分页

那本文想说的就是这个前端分页:

实现效果:

前端分页的实现

在线预览地址

首先的问题是可以获取到全部数据的情况下,怎么实现分页
其实这个问题很简单,全部数据取到的情况下,那当然是点到哪个页面是显示那页的内容即可,只要展示对应内容即可。

正常简单分页

例子:有个数组[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],数组长度为16,比如要每页5条数据,然后每页页就是[0,1,2,3,4]、[5,6,7,8,9]、[10,11,12,13,14]、[15]

实现如下:

前端分页的实现

function getPageDate(page){
   const arr1 = arr
   return arr1.slice((page-1)*5,page*5)
}

这个分页就是属于已经pageSize=5,然后总列表知道,简单的求第n页的数组数据

回归项目中的分页

已知的参数整理:

  • 分页方面:当前页数currentPage,还有个多少数据为一页的pageSize
  • 数据方面:首先我们有个全部数据的列表allLists,然后求展示的数组定义为showLists

根据上面已知的我们又可以知道一些额外的参数

  • allLists.length就是数据总条数
  • Math.ceil(allLists.length / pageSize)是总页数 Math.ceil是有小数向上取整,设置成totalPage

改进前分页

实现分页:

if(totalPage===1){
  // 只有一页的情况
  showLists=allLists
}else{
  // 不止一页的情况 获取当前页数据
  showLists = allLists.slice((currentPage-1)*pageSize,currentPage*pageSize)
}

然后展示获取到的showLists就行,由于项目中数据是按时间升序的返回,这样的话新增留言就只能点击末页才能看见,如果我是留言的人,肯定希望自己留了言就能看见,而不是去手动去末页找,说两个解决办法

  • 最简单的就是返回是升序那我来个反转reverse()变成降序,那不是轻轻松松解决
  • 切割数据的方法重新改进一下

那我在这当然是去说明一下第二种方法

if(totalPage===1){
  // 只有一页的情况
  showLists=allLists
}else{
  // 不止一页的情况 获取当前页数据
  showLists = allLists.slice(allLists.length-currentPage*pageSize,allLists.length-(currentPage-1)*pageSize)
}

如果你这样写,那就考虑不全了,因为计算最后一页的时候allLists.length-currentPage*pageSize可能是负数,所以需要改进一下,要么去考虑最后一页的情况,要么去判断这个allLists.length-currentPage*pageSize是否小于0

//修改 判断是否小于0
showLists = allLists.slice(allLists.length-currentPage*pageSize<0?0:showLists = allLists.slice(allLists.length-currentPage*pageSize,allLists.length-(currentPage-1)*pageSize),allLists.length-(currentPage-1)*pageSize)
//或者 直接考虑totlePage===currentPage(当前页是否等于总页数?),为true就是最后一页 

改进分页

到目前这样的思路去解决分页,到这也是我部署的第一版分页的情况,但是我自己用着用发现一个新问题,大于1页的时候,第一页是总是满的,因为我们取第一页数据的时候是取最后pageSize条数的数据,用户体验还不够好,显得页面比较乱,继续改进成先满足除了第一页的情况是满pageSize条,剩下的才放在第一条

if(totlePage===1){
// 只有一页的情况
  showLists=allLists }
else{
  // 不止一页当前 获取当前页数据
  showLists = allLists.slice((totlePage-currentPage)*pageSize,(totlePage-currentPage+1)*pageSize
}

这样实现的话为什么不考虑第一页的情况,其实这样的情况当为第一页是取(totlePage-1)*pageSize,totlePage*pageSize间的数据,比如总条数=16,pageSige=5,那可得totalPage=4,整个数组.slice(15,20),也就是取15之后的所有数据(这里其实就一条),
当然你要是不理解可以增加一个判断是否为第一页,为第一页的时候去取

showLists = allLists.slice((totlePage-currentPage)*pageSize,allLists.length)
// 也就是slice(15,16)而不是slice(15,20)

改进前后实现的效果

都是首页,页数大于1,数据条数一样,

  • 改进前第一页展示最新30条数据,第二页展示剩余13条。
  • 改进后第一页展示最新13条数据,第二页展示剩余30条。
    但是展示效果我还是更喜欢改进后的:

前端分页的实现

前端分页的实现

留言条数计算

细心的你肯定发现了每条留言上方都有标注当前是第几条留言,简单说一下实现,首先肯定用计算属性去得到,然后根据是当前几页和在当前页数的留言序号去计算,参数v为当前页数的留言序号,我这里30为pageSize

改进前获取留言index

改进前的计算index比较复杂点,如果当前页是最后一页直接返回v,但是不是当前页需要使用总条数msgLength-pageSize*(totlaPage-currentPage)+v,这个公式解释一下就是:先计算除了当前页和小于当前页的条数pageSize*(totlaPage-currentPage),那总条数减去它就变成了大于当前页的总条数,也就是当前页序号的起点然后再加个序号,完美求得所需要的

 // 获取当前第几条留言
    getNumber(v){
      if (this.totlaPage === this.currentPage) {
        return v
      }else{
        return (this.msgLength-30*(this.totlaPage - this.currentPage) + v)
      }
    },

改进后获取留言index

改进后就简单多了,当前序号加上后面页数*页面条数30

    // 获取当前第几条留言
    getNumber(v){
       return 30*(this.totlaPage - this.currentPage) + v
    },

本文小结

上面所说的可能是偏理论+自己盲打的代码,没有去说明分页组件怎么用之类,偏理论,也是对留言墙的中前端分页的实现的简单说明,要是觉得不错,动动你的小手指!
熟能生巧(Practice make perfect!)。

前端分页的实现

上一篇:【HIT-计算机系统】ICS-Lab7 TinyShell


下一篇:分页工具类PageUtil