添加分页组件
- 实现分页导航功能 - 添加分页样式
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