添加分页组件
- 实现分页导航功能 - 添加分页样式
This commit is contained in:
parent
269c66d1ac
commit
a3561609f5
120
src/components/Pagination.css
Normal file
120
src/components/Pagination.css
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/* 自定义分页组件样式 */
|
||||||
|
.custom-pagination {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 16px 0;
|
||||||
|
border-top: 1px solid #f0f0f0;
|
||||||
|
background: #fafafa;
|
||||||
|
border-radius: 0 0 6px 6px;
|
||||||
|
margin: 0 -24px -24px -24px;
|
||||||
|
padding-left: 24px;
|
||||||
|
padding-right: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-page-item {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin: 0 2px;
|
||||||
|
font-size: 14px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-page-item:hover {
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
border-color: #1890ff;
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-page-item.active {
|
||||||
|
background-color: #1890ff;
|
||||||
|
color: #ffffff;
|
||||||
|
border-color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-page-item.active:hover {
|
||||||
|
background-color: #40a9ff;
|
||||||
|
border-color: #40a9ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-page-item.disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
color: #d9d9d9;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-color: #d9d9d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-page-item.disabled:hover {
|
||||||
|
color: #d9d9d9;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-color: #d9d9d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-ellipsis {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
cursor: default;
|
||||||
|
border: none;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-jumper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-page-info {
|
||||||
|
min-width: 80px;
|
||||||
|
text-align: right;
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式设计 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.custom-pagination {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-info {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-controls {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-jumper {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
210
src/components/Pagination.js
Normal file
210
src/components/Pagination.js
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
/**
|
||||||
|
* 自定义分页组件
|
||||||
|
* 支持页码跳转、页面大小选择等功能
|
||||||
|
*/
|
||||||
|
import React from 'react';
|
||||||
|
import { Select, Input, Button, Space, Typography } from 'antd';
|
||||||
|
import './Pagination.css';
|
||||||
|
import {
|
||||||
|
LeftOutlined,
|
||||||
|
RightOutlined,
|
||||||
|
DoubleLeftOutlined,
|
||||||
|
DoubleRightOutlined
|
||||||
|
} from '@ant-design/icons';
|
||||||
|
|
||||||
|
const { Option } = Select;
|
||||||
|
const { Text } = Typography;
|
||||||
|
|
||||||
|
const Pagination = ({
|
||||||
|
current = 1,
|
||||||
|
total = 0,
|
||||||
|
pageSize = 10,
|
||||||
|
showSizeChanger = true,
|
||||||
|
showQuickJumper = true,
|
||||||
|
showTotal = true,
|
||||||
|
onChange,
|
||||||
|
onShowSizeChange,
|
||||||
|
pageSizeOptions = ['10', '20', '50', '100'],
|
||||||
|
style = {}
|
||||||
|
}) => {
|
||||||
|
const totalPages = Math.ceil(total / pageSize);
|
||||||
|
|
||||||
|
// 计算显示的页码范围
|
||||||
|
const getVisiblePages = () => {
|
||||||
|
const pages = [];
|
||||||
|
const delta = 2; // 当前页前后显示的页数
|
||||||
|
|
||||||
|
if (totalPages <= 7) {
|
||||||
|
// 总页数较少时显示所有页码
|
||||||
|
for (let i = 1; i <= totalPages; i++) {
|
||||||
|
pages.push(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 总页数较多时显示部分页码
|
||||||
|
let start = Math.max(1, current - delta);
|
||||||
|
let end = Math.min(totalPages, current + delta);
|
||||||
|
|
||||||
|
if (current <= delta + 1) {
|
||||||
|
end = Math.min(totalPages, 2 * delta + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current >= totalPages - delta) {
|
||||||
|
start = Math.max(1, totalPages - 2 * delta - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start > 1) {
|
||||||
|
pages.push(1);
|
||||||
|
if (start > 2) {
|
||||||
|
pages.push('...');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = start; i <= end; i++) {
|
||||||
|
pages.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end < totalPages) {
|
||||||
|
if (end < totalPages - 1) {
|
||||||
|
pages.push('...');
|
||||||
|
}
|
||||||
|
pages.push(totalPages);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pages;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理页码点击
|
||||||
|
const handlePageClick = (page) => {
|
||||||
|
if (page !== current && page >= 1 && page <= totalPages) {
|
||||||
|
onChange?.(page, pageSize);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理页面大小变化
|
||||||
|
const handlePageSizeChange = (newPageSize) => {
|
||||||
|
const newCurrent = Math.min(current, Math.ceil(total / newPageSize));
|
||||||
|
onShowSizeChange?.(newCurrent, newPageSize);
|
||||||
|
onChange?.(newCurrent, newPageSize);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理快速跳转
|
||||||
|
const handleQuickJump = (e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
const page = parseInt(e.target.value, 10);
|
||||||
|
if (page >= 1 && page <= totalPages) {
|
||||||
|
handlePageClick(page);
|
||||||
|
e.target.value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 使用CSS类而不是内联样式
|
||||||
|
|
||||||
|
if (total === 0) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="custom-pagination" style={style}>
|
||||||
|
{/* 左侧信息显示 */}
|
||||||
|
<div className="pagination-info">
|
||||||
|
{showTotal && (
|
||||||
|
<Text type="secondary">
|
||||||
|
共 {total} 条记录
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{showSizeChanger && (
|
||||||
|
<Space>
|
||||||
|
<Text type="secondary">每页显示</Text>
|
||||||
|
<Select
|
||||||
|
value={pageSize}
|
||||||
|
onChange={handlePageSizeChange}
|
||||||
|
size="small"
|
||||||
|
style={{ width: '80px' }}
|
||||||
|
>
|
||||||
|
{pageSizeOptions.map(size => (
|
||||||
|
<Option key={size} value={parseInt(size, 10)}>
|
||||||
|
{size}
|
||||||
|
</Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
<Text type="secondary">条</Text>
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 中间页码控制 */}
|
||||||
|
<div className="pagination-controls">
|
||||||
|
{/* 首页和上一页 */}
|
||||||
|
<div
|
||||||
|
className={`pagination-page-item ${current === 1 ? 'disabled' : ''}`}
|
||||||
|
onClick={() => current !== 1 && handlePageClick(1)}
|
||||||
|
title="首页"
|
||||||
|
>
|
||||||
|
<DoubleLeftOutlined />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={`pagination-page-item ${current === 1 ? 'disabled' : ''}`}
|
||||||
|
onClick={() => current !== 1 && handlePageClick(current - 1)}
|
||||||
|
title="上一页"
|
||||||
|
>
|
||||||
|
<LeftOutlined />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 页码 */}
|
||||||
|
{getVisiblePages().map((page, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className={
|
||||||
|
page === '...'
|
||||||
|
? 'pagination-ellipsis'
|
||||||
|
: `pagination-page-item ${page === current ? 'active' : ''}`
|
||||||
|
}
|
||||||
|
onClick={() => page !== '...' && handlePageClick(page)}
|
||||||
|
>
|
||||||
|
{page}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* 下一页和末页 */}
|
||||||
|
<div
|
||||||
|
className={`pagination-page-item ${current === totalPages ? 'disabled' : ''}`}
|
||||||
|
onClick={() => current !== totalPages && handlePageClick(current + 1)}
|
||||||
|
title="下一页"
|
||||||
|
>
|
||||||
|
<RightOutlined />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={`pagination-page-item ${current === totalPages ? 'disabled' : ''}`}
|
||||||
|
onClick={() => current !== totalPages && handlePageClick(totalPages)}
|
||||||
|
title="末页"
|
||||||
|
>
|
||||||
|
<DoubleRightOutlined />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 右侧快速跳转 */}
|
||||||
|
<div className="pagination-jumper">
|
||||||
|
{showQuickJumper && (
|
||||||
|
<Space>
|
||||||
|
<Text type="secondary">跳至</Text>
|
||||||
|
<Input
|
||||||
|
size="small"
|
||||||
|
style={{ width: '50px' }}
|
||||||
|
placeholder=""
|
||||||
|
onKeyPress={handleQuickJump}
|
||||||
|
/>
|
||||||
|
<Text type="secondary">页</Text>
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
|
<div className="pagination-page-info">
|
||||||
|
<Text type="secondary">
|
||||||
|
{current} / {totalPages} 页
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Pagination;
|
||||||
Loading…
Reference in New Issue
Block a user