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

本文介绍了如何使用Typescript从零开始开发一个类似antd的分页器,包括分页核心代码的实现逻辑。通过分析antd分页器的页码显示规律,提出两种实现思路,并详细讲解了第二种思路,通过`showPages`函数实现了分页器的动态页码显示。此外,还涵盖了组件的默认配置、参数接口、工具函数、事件绑定和回调等关键部分的开发。
摘要由CSDN通过智能技术生成

本文是使用 Typescript 开发类 antd 分页器,并发布 npm 的第二篇,因为最近在业务中使用了 antd 中的 Pagination 开发了相关业务,而自己又对组件的封装由很有兴趣,所以打算用 ts 来封装一个具有 antd 所有功能的 Pagination。相信你也能轻轻松松的发布一个 npm 组件了。

相关系列文章

从零开始实现类 antd 分页器(一):搭建项目架构

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

从零开始实现类 antd 分页器(三):发布npm

写作过程中有些方法的具体实现没有讲到,大家可以自行查看源码。本案例项目仓库:

闲来无事,造个轮子 —— darrell-wheels

为了写作方便,antd 的 分页器我统一以 antd-pagination 代替,自己的分页器统一以 my-pagination 代替。

效果图

基础 + 更多

跳转页数 [ 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 = '';

...

// 待完成的逻辑

...

return str.trim();

}

// 总页数

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 >

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值