前言
这是在 Ant Design Pro 4 中基于 ant design 的 Pagination 分页组件的基础上开发的。
有这么一个需求, 页码的颜色基于该页是否有差异, 没有差异就正常颜色, 有差异就显示红色, 我就在 ant design 这个分页的基础上写了一个分页
框架链接
效果图
分页数据结构
// diffQuantity 代表该页差异数量
// page 代表页码
[
{diffQuantity: 0, page: 0},
{diffQuantity: 0, page: 1},
{diffQuantity: 0, page: 2},
{diffQuantity: 3, page: 3}
]
代码
import React, { useEffect, useState, useMemo } from 'react';
import { Button, Row, Col } from 'antd';
import { LeftOutlined, RightOutlined } from '@ant-design/icons';
import "./NewPageModule.less";
// 分页
function PageView({ results, current, handlePaging }) {
// 分页源数据
const [list, setList] = useState([]);
// 分页函数
const onChange = (page, list) => {
try {
if (typeof page !== "number" || !Array.isArray(list)) {
throw `数据有误page: ${page}, list: ${list}`;
}
if (list.length < 21) return list;
// 坐标数据
let beforeStart, beforeEnd;
let afterStart, afterEnd;
// 总长
const len = list.length;
// 当前页
const currentPage = page + 1;
// 前两个
let before = [list[0] , { page: page - 5 >= 0 ? page - 5 : 0, icon: "before" }];
// 后三个
let after = [{ page: page + 5 <= len ? page + 5 : len - 1, icon: "after" }, list.lastItem];
// 当前页为前 4 个
if (currentPage <= 4) {
// 清除默认值
before = [];
// 前坐标
beforeStart = 0;
beforeEnd = page;
// 后坐标
afterStart = page;
afterEnd = 5; // 5
if (currentPage === 4) {
afterEnd = page + 3; // 6
}
// 当前页为倒数 4 个
} else if (currentPage >= len - 3) {
// 清除默认值
after = [];
// 前坐标
if (currentPage === len - 3) {
beforeStart = len - 6; // 74
beforeEnd = len;
} else {
beforeStart = len - 5; // 75
beforeEnd = len;
}
// 后坐标
afterStart = 0;
afterEnd = 0;
// 中间正常数
} else {
// 前坐标
beforeStart = page - 2;
beforeEnd = page;
// 后坐标
afterStart = page;
afterEnd = page + 3;
}
// 获取前两个
before = before.concat(list.slice(beforeStart, beforeEnd));
// 获取后三个
after = list.slice(afterStart, afterEnd).concat(after);
const res = before.concat(after);
// console.log("before ==> ", before, "after ==> ", after);
// console.log(res, "res");
return res;
} catch (error) {
console.log(error, "分页 onChange");
return [];
}
};
// 分页数据
const pageList = useMemo(() => {
if (list.length) {
return onChange(current, list);
}
return [];
}, [current, list]);
useEffect(() => {
// if (Array.isArray(results) && results.length) {
// let da = results.map(it => ({ diffQuantity: it.diffQuantity, page: it.page }));
// da.length = 20;
const da = [];
for (let i = 0; i < 72; i++) {
da.push({
diffQuantity: i % 3 === 0 ? i : 0,
page: i,
})
}
setList(da);
// }
}, [results]);
return (
<Row>
<Col span={18}>
<div style={{ display: 'flex', justifyContent: 'center' }}>
<ul className="ant-pagination mini" unselectable="unselectable">
<li className="ant-pagination-prev" title="上一页">
<Button
size="small"
type="link"
disabled={current === 0}
onClick={() => handlePaging(current - 1)}
>
<LeftOutlined />
</Button>
</li>
{pageList.map((it, i) => {
if (it.icon === "before") {
return (
<li
className="ant-pagination-jump-prev ant-pagination-jump-prev-custom-icon"
key={i.toString()}
title="向前 5 页"
onClick={handlePaging.bind(null, it.page)}
>
<a className="ant-pagination-item-link">
<div className="ant-pagination-item-container">
<span role="img" aria-label="double-left" className="anticon anticon-double-left ant-pagination-item-link-icon">
<svg viewBox="64 64 896 896" focusable="false" className="" data-icon="double-left" width="1em" height="1em" fill="currentColor" aria-hidden="true">
<path d="M272.9 512l265.4-339.1c4.1-5.2.4-12.9-6.3-12.9h-77.3c-4.9 0-9.6 2.3-12.6 6.1L186.8 492.3a31.99 31.99 0 000 39.5l255.3 326.1c3 3.9 7.7 6.1 12.6 6.1H532c6.7 0 10.4-7.7 6.3-12.9L272.9 512zm304 0l265.4-339.1c4.1-5.2.4-12.9-6.3-12.9h-77.3c-4.9 0-9.6 2.3-12.6 6.1L490.8 492.3a31.99 31.99 0 000 39.5l255.3 326.1c3 3.9 7.7 6.1 12.6 6.1H836c6.7 0 10.4-7.7 6.3-12.9L576.9 512z"></path>
</svg>
</span>
<span className="ant-pagination-item-ellipsis">•••</span>
</div>
</a>
</li>
)
}
if (it.icon === "after") {
return (
<li
className="ant-pagination-jump-next ant-pagination-jump-next-custom-icon"
key={i.toString()}
title="向后 5 页"
onClick={handlePaging.bind(null, it.page)}
>
<a className="ant-pagination-item-link">
<div className="ant-pagination-item-container">
<span role="img" aria-label="double-right" className="anticon anticon-double-right ant-pagination-item-link-icon">
<svg viewBox="64 64 896 896" focusable="false" className="" data-icon="double-right" width="1em" height="1em" fill="currentColor" aria-hidden="true">
<path d="M533.2 492.3L277.9 166.1c-3-3.9-7.7-6.1-12.6-6.1H188c-6.7 0-10.4 7.7-6.3 12.9L447.1 512 181.7 851.1A7.98 7.98 0 00188 864h77.3c4.9 0 9.6-2.3 12.6-6.1l255.3-326.1c9.1-11.7 9.1-27.9 0-39.5zm304 0L581.9 166.1c-3-3.9-7.7-6.1-12.6-6.1H492c-6.7 0-10.4 7.7-6.3 12.9L751.1 512 485.7 851.1A7.98 7.98 0 00492 864h77.3c4.9 0 9.6-2.3 12.6-6.1l255.3-326.1c9.1-11.7 9.1-27.9 0-39.5z"></path>
</svg>
</span>
<span className="ant-pagination-item-ellipsis">•••</span>
</div>
</a>
</li>
)
}
// 当前页码颜色
const curActive = it.diffQuantity ? "diff_item_active ant-pagination-item-active" : "ant-pagination-item-active";
const currentColor = it.page === current ? curActive : '';
// 每页颜色
const pageColor = it.diffQuantity ? "diff_item" : "";
return (
<li
className={`ant-pagination-item ant-pagination-item-${it.page + 1} ${currentColor} ${pageColor}`}
onClick={handlePaging.bind(null, it.page)}
title={`${it.page + 1}`}
key={i.toString()}
>
{`${it.page + 1}`}
</li>
)
})}
<li className="ant-pagination-next" title="下一页">
<Button
size="small"
type="link"
disabled={current === results.lastIndex}
onClick={() => handlePaging(current + 1)}
>
<RightOutlined />
</Button>
</li>
</ul>
</div>
</Col>
</Row>
);
};
export default PageView;
样式
@import '~antd/es/style/themes/default.less';
// 差异当前页的颜色
.diff_item_active {
border-color: #ff0000 !important;
}
// 差异页颜色
.diff_item {
color: #ff0000 !important;
}
// .ant-pagination-item:hover {
// // border-bottom: 3px solid #1890ff;
// // border-color: #ff0000 !important;
// }