前言
这两天写了一个个人项目-留言墙:一个以在线便利签的形式,也可以扩展成许愿墙、树洞的一个项目。上篇文章地址链接:留言墙
起先功能点很少,后面慢慢加入了一些留言总的建议性改造或者优化。比如:
- 增加字体和标题颜色
- 增加分页
那本文想说的就是这个前端分页:
实现效果:
首先的问题是可以获取到全部数据的情况下,怎么实现分页
其实这个问题很简单,全部数据取到的情况下,那当然是点到哪个页面是显示那页的内容即可,只要展示对应内容即可。
正常简单分页
例子:有个数组[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!)。