介绍
这篇文章我们继续讲解Ant Design中的Table
组件,今天我们来看看如何为Table
组件添加分页功能。随着项目的进行,数据量会变得越来越大,一页不可能显示所有的数据,所以分页功能就非常必要了。
为Table组件添加分页功能
为了实现分页,我们首先模拟一些数据,假设后端API返回100条数据,我们改造一下fetchUsers
这个方法,动态生成100条User数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| export async function fetchUsers() { const users: User[] = Array.from({ length: 100 }, (_, index) => ({ id: index + 1, name: `User${index + 1}`, email: `user${index + 1}@gmail.com`, phone: `130${Math.floor(10000000 + Math.random() * 90000000)}`, }));
return new Promise<{ data: User[] }>((resolve) => { setTimeout(() => { resolve({ data: users }); }, 1000); }); }
|
现在运行程序,发现分页功能已经自动启用了,这是因为Ant Design的Table
组件默认会启用分页功能。但是这个分页实际上是纯前端的分页,也就是说,Table
组件会把所有数据都加载到前端,然后自己在前端进行分页,这样做的缺点是如果数据量非常大,前端加载时间会很长,用户体验会很差。
所以,真正的分页一定需要后端api的支持,前端只需要传递当前页码和每页条数给后端,后端返回对应页码的数据即可。我们改造一下fetchUsers
方法,模拟后端分页的api。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import { User } from "./User";
export async function fetchUsers(pageNumber: number, pageSize: number = 10): Promise<{ data: User[] }> { const users: User[] = Array.from({ length: 100 }, (_, index) => ({ id: index + 1, name: `User${index + 1}`, email: `user${index + 1}@gmail.com`, phone: `130${Math.floor(10000000 + Math.random() * 90000000)}`, }));
const pageData = users.slice((pageNumber - 1) * pageSize, pageNumber * pageSize);
return new Promise<{ data: User[] }>((resolve) => { setTimeout(() => { resolve({ data: pageData }); }, 1000); }); }
|
然后改造一下getUsers
方法,传递页码和每页条数给fetchUsers
方法。
1 2 3 4 5 6 7 8 9 10 11
| const getUsers = async (pageNumber: number, pageSize?: number) => { try { setLoading(true); const res = await fetchUsers(pageNumber, pageSize); setTableData(res.data); } catch (error) { console.error('Error fetching users:', error); } finally { setLoading(false); } };
|
接下来在useEffect
中调用getUsers
方法时,传递页码1。
1 2 3
| useEffect(() => { getUsers(1); }, []);
|
这时候,你会发现Table组件右下角没有分页了,只显示了一个页码1,这是因为我们只返回了一页数据,要开启分页功能必须返回一个total
参数告知Table组件数据的总数。
我们在fetchUsers
方法中添加一个total
参数,表示数据的总数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import { User } from "./User";
export interface FetchUsersResponse { data: User[]; total: number; }
export async function fetchUsers(pageNumber: number, pageSize: number = 10): Promise<FetchUsersResponse> { const users: User[] = Array.from({ length: 100 }, (_, index) => ({ id: index + 1, name: `User${index + 1}`, email: `user${index + 1}@gmail.com`, phone: `130${Math.floor(10000000 + Math.random() * 90000000)}`, }));
const pageData = users.slice((pageNumber - 1) * pageSize, pageNumber * pageSize);
return new Promise<FetchUsersResponse>((resolve) => { setTimeout(() => { const response: FetchUsersResponse = { data: pageData, total: users.length }; resolve(response); }, 1000); }); }
|
在Users页面,我们需要定一个state来保存total
。
1
| const [total, setTotal] = useState(0);
|
然后在获取数据时,设置total
。
1 2 3 4 5 6 7 8 9
| const getUsers = async (pageNumber: number, pageSize?: number) => { try { setLoading(true); const res = await fetchUsers(pageNumber, pageSize); setTableData(res.data); setTotal(res.total); } };
|
最后,在Table组件中传递total属性,并响应onChange
函数,在用户切换页面时,获取对应的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13
| <Table loading={loading} dataSource={tableData} columns={columns} rowKey={'id'} pagination={{ pageSize: 10, total: total, onChange: (page) => { getUsers(page); }, }} />
|
此时重新运行程序,然后点击不同的页码,你会发现数据会根据页码变化而变化,这样分页功能就实现了。但是当你改变每页显示的条数时,你会发现数据并没有变化,这是因为我们在onChange
函数中没有传递每页条数,而是将每页条数固定为10条了,我们需要改造一下onChange
函数,传递每页条数。
我们可以添加一个新函数来响应Table组件的onChange
事件。
1 2 3 4
| const onPageChange = (pageNumber: number, pageSize: number) => { setPageNumber(pageNumber); setPageSize(pageSize); };
|
然后将pageNumber
和pageSize
保存到state中。
1 2
| const [pageNumber, setPageNumber] = useState(1); const [pageSize, setPageSize] = useState(10);
|
并更新useEffect
,将pageNumber
或pageSize
作为依赖变量,这样当他们变化时,重新获取数据。
1 2 3
| useEffect(() => { getUsers(pageNumber, pageSize); }, [pageNumber, pageSize]);
|
最后在Table组件中传递onPageChange
函数。
1 2 3 4 5 6 7 8 9 10
| <Table loading={loading} dataSource={tableData} columns={columns} rowKey={'id'} pagination={{ total: total, onChange: onPageChange, }} />
|
再次刷新页面,一切正常,分页功能完美实现。
禁用sizeChanger
如果你不希望用户改变每页显示的条数,可以禁用sizeChanger
功能,只需要在pagination
属性中添加showSizeChanger: false
即可。
1 2 3 4 5 6 7 8 9
| <Table loading={loading} dataSource={tableData} columns={columns} rowKey={'id'} pagination={{ showSizeChanger: false, }} />
|
禁用分页
如果你十分确定,你的数据一页就能展示完,比如10条以内的数据,那么你可以禁用分页功能。只需要在Table
组件中添加pagination={false}
属性即可。
1 2 3 4 5 6 7
| <Table loading={loading} dataSource={tableData} columns={columns} rowKey={'id'} pagination={false} />
|
今天就到这里了,祝大家编程愉快,我们明天见!觉得有用,就点个关注吧!