antd自定义分页器_从零开始实现类antd分页器(二):分页核心代码

antd⾃定义分页器_从零开始实现类antd分页器(⼆):分页
核⼼代码
本⽂是使⽤ Typescript 开发类 antd 分页器,并发布 npm 的第⼆篇,因为最近在业务中使⽤了 antd 中的 Pagination 开发了相关业务,⽽⾃⼰⼜对组件的封装由很有兴趣,所以打算⽤ ts 来封装⼀个具有 antd 所有功能的 Pagination。相信你也能轻轻松松的发布⼀个 npm 组件了。
相关系列⽂章
从零开始实现类 antd 分页器(⼀):搭建项⽬架构
从零开始实现类 antd 分页器(⼆):分页核⼼代码
从零开始实现类 antd 分页器(三):发布npm
写作过程中有些⽅法的具体实现没有讲到,⼤家可以⾃⾏查看源码。本案例项⽬仓库:
闲来⽆事,造个轮⼦ —— darrell-wheels
为了写作⽅便,antd 的 分页器我统⼀以 antd-pagination 代替,⾃⼰的分页器统⼀以 my-pagination 代
jumper2替。
效果图
基础 + 更多
跳转页数 [ showQuickJumper ] + 改变页数 [ showSizeChanger ]
迷你 [ size: 'small' ]
简洁 [ simple: true ]
显⽰总数 [ showTotal ]
修改上⼀步和下⼀步相应⽂字 [ itemRender ]
分页逻辑
这⾥⾯的逻辑是实现这个分页器最最关键的地⽅,同时也是分页器的难点所在。
我们要计算出每⼀页的页码排布情况,什么时候该显⽰省略号,什么时候改成全部显⽰等等。
antd 的分页
我试了⼀下 antd-pagination 的页码显⽰,假设有 30 页,它的页码是如下分布的,我们以 allPages 代表总页数,current 代表当前是第⼏页:
// allPages = 30
当 current = 1, 显⽰ 1 2 3 4 5 (30)
当 current = 2, 显⽰ 1 2 3 4 5 (30)
当 current = 3, 显⽰ 1 2 3 4 5 (30)
当 current = 4, 显⽰ 1 2 3 4 5 6 (30)
当 current = 5, 显⽰ 1 ... 3 4 5 6 7 (30)
...
当 current = 13, 显⽰ 1 ... 11 12 13 14 15 (30)
当 current = 14, 显⽰ 1 ... 12 13 14 15 16 (30)
当 current = 15, 显⽰ 1 ... 13 14 15 16 17 (30)
当 current = 16, 显⽰ 1 ... 14 15 16 17 18 (30)
...
当 current = 26, 显⽰ 1 ... 24 25 26 27 28 (30)
当 current = 27, 显⽰ 1 ... 25 26 27 28 29 30
当 current = 28, 显⽰ 1 ... 26 27 28 29 30
当 current = 29, 显⽰ 1 ... 26 27 28 29 30
当 current = 30, 显⽰ 1 ... 26 27 28 29 30
复制代码
在 antd-pagination 有⼀个参数 showLessItems,当它为 true 时,意思是当前页⾯ 左右显⽰各 1 个,为 false 时,代表当前页⾯ 左右各显⽰ 2 个。在这⾥我们把 当前页⾯ 左右显⽰⼏个 暂且记为 pageBufferSize,
也就是说,antd-pagination 的 pageBufferSize 只有两个值 1 和 2,不过两个已经完全够了。
上⾯的例⼦,pageBufferSize = 2,及 showLessItems 为 false。
规律
接着观察上⾯这⼀组数据,我们可以⼀下规律,粗粗⼀看,我们会发现:
第 1 页 到 第 3 页 显⽰的页码是⼀样的,只有 ⼀个后⾯省略号
第 4 页 ⽐ 前 3 页 多了⼀个页码,但是还是只有 ⼀个后⾯省略号(临界点)
第 5 页 开始,到 第 26 页 出现了 两个省略号,并且中间都是 5 个
第 27 页 跟第四页类似 ⼜回到了 ⼀个前⾯省略号(临界点)
第 28 页 到 第 30 页,显⽰的页⾯⼀样,并只有 ⼀个前⾯省略号。
代码实现
我们在这⾥先暂时不考虑复杂的 dom 输出,只使⽤简单的字符串输出。
这⾥笔者想到两种思路:
第⼀种思路
简单粗暴:就是把⽤代码翻译上⾯我们发现的规律,我们可以⽤ allPages、current、pageBufferSize 来表⽰:
// 临界点
当 current = 5,转化为代码 1 + pageBufferSize * 2
当 current = 26,转化为代码 allPages - pageBufferSize * 2
// 在临界点 区域内,都是双省略号
current >= 1 + pageBufferSize * 2 && current <= allPages + pageBufferSize * 2
// 然后在对 第4页 和 第27页做⼀下特殊处理
// 这两页的页码虽然只有⼀个省略号,但是⽐正常的会多出⼀个页码
当 current = 4,转化为代码 pageBufferSize * 2
当 current = 27,转化为代码 allPages - pageBufferSize * 2 + 1
// 接下来就是最简单的
当 current = 1 || 2 || 3,转化为代码 < pageBufferSize * 2 - 1
当 current = 28 || 29 || 30,> allPages - pageBufferSize * 2 + 1
复制代码
第⼆种思路
我们主要来讲⼀下第⼆种思路,这个也是 antd-pagination 内使⽤的⽅法,我们接下来的⽅法也只满⾜ pageBufferSize 为 1 或者 2 。
我们定义⼀个函数 showPages ⽅法来实现相关的逻辑;
/**
* 输出每⼀页 显⽰的页码 的 字符串
* @param current:当前页码;
* @param allPages:总页数;
* @param pageBufferSize:页数左右两边显⽰⼏个(1个 或 2个)
*/
function showPages (current, allPages, pageBufferSize){
let str = '';
...
// 待完成的逻辑
...
im();
}
// 总页数
let total = 30;
// 循环输出每页的页码字符串
for (let i = 1; i <= total; i++) {
console.log(showPages(i, total, 2));
}
复制代码
⾸先 antd-pagination 当总页数⼩于等于 5 + 2 * pageBufferSize 的时候,不管 current 是 第⼏页,所有的页码都会展现,我们可以在showPages 添加如下代码:
// 当总页数 <= 5 + 2 * pageBufferSize
function showPages (current, allPages, pageBufferSize){
if (allPages <= 5 + pageBufferSize * 2) {
for (let i = 1; i <= allPages; i++) {
str = str + ' ' + i;
}
}
}
复制代码
此时我们设置 allPages = 8,在浏览器中我们可以看到如下图所⽰:
观察上⾯的字符串我们发现,当有两个省略号的时候,前⾯字符肯定是 1 ...,最后两个字符肯定是 ... 30。
1. 先循环输出 当前页码 与 页码前后 pageBufferSize 个数
我们在代码⾥⾯定义⼀个 left,代表字符串循环从这个数开始;再定义 right,代表字符串循环到此结束。left 的值根据前⼏页的 current 和 pageBufferSize ,我们很简单的可以得到。
let left = Math.max(1, current - pageBufferSize);
复制代码
同理可以得到 right 的值:
let right = Math.min(current + pageBufferSize, allPages);
复制代码
因为 前三页 和 后三页 都是显⽰ 5 个数的,所以在这种情况下,我们要对 left 和 right 在根据 pageBufferSize 做⼀个调整:
if (current - 1 <= pageBufferSize) {
right = 1 + pageBufferSize * 2;
}
if (allPages - current <= pageBufferSize) {
left = allPages - pageBufferSize * 2;
}
复制代码
接着我们便可以循环输出了:
for (let i = left; i <= right; i++) {
str = str + ' ' + i;
}
复制代码
2. 然后再去拼相关的省略号
接下来我们就要给上⾯的 str 拼省略号了。
这这我们在第⼀种思路⾥⾯讲过,我们可以很快的写出如下代码:
if (current - 1 >= pageBufferSize * 2) {
str = '... ' + str;
}
if (allPages - current >= pageBufferSize * 2) {
str = str + ' ...';
}
复制代码
这⾥⾯需要注意⼀个点,这个判断⽅法在 pageBufferSize = 1 的时候,在第3页 和 allPages - 2 页会出现问题,如图所⽰:
所以我们要在加上对这个的判断:
if (current - 1 >= pageBufferSize * 2 && current !== 1 + 2) {
str = '... ' + str;
}
if (allPages - current >= pageBufferSize * 2 && current !== allPages - 2) {
str = str + ' ...';
}
复制代码
3. 最后再去⽐较第⼀个值和最后⼀个值 是不是 1 和 总页数。
省略号我们加完之后,我们就只剩最后⼀步了。我们需要判断 第⼀步的 left 和 right 是不是第 1 页和 最后⼀页,我们可以写出以下代码:if (left !== 1) {
str = 1 + ' ' + str;
}
if (right !== allPages) {
str = str + ' ' + allPages;
}
复制代码
到这⾥我们的分页逻辑算是⼤功告成,完整的代码如下:
function showPages (current, allPages, pageBufferSize){
let str = '';
if (allPages <= 5 + pageBufferSize * 2) {
for (let i = 1; i <= allPages; i++) {
str = str + ' ' + i;
}
} else {
let left = Math.max(1, current - pageBufferSize);
let right = Math.min(current + pageBufferSize, allPages);
if (current - 1 <= pageBufferSize) {

本文发布于:2024-09-22 06:56:29,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/3/352015.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:代码   页码   省略号
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议