Fluent UI数据表格分页:客户端与服务器端分页实现
【免费下载链接】fluentui 项目地址: https://gitcode.com/GitHub_Trending/of/fluentui
在数据展示场景中,表格分页是提升用户体验的关键功能。本文将基于Fluent UI组件库,详细介绍客户端与服务器端两种分页模式的实现方案,帮助开发者根据数据规模选择合适的分页策略。
分页模式对比
| 模式 | 适用场景 | 数据处理位置 | 优势 | 限制 |
|---|---|---|---|---|
| 客户端分页 | 数据量<1000条 | 浏览器内存 | 无网络延迟、交互流畅 | 初始加载慢、占用内存高 |
| 服务器端分页 | 数据量>1000条 | 后端数据库 | 按需加载、节省资源 | 依赖网络请求、实现复杂 |
Fluent UI表格组件基础
Fluent UI提供DataGrid组件作为数据表格解决方案,核心文件路径:
- 组件定义:packages/react-components/react-table/library/src/components/DataGrid/DataGrid.tsx
- 类型定义:packages/react-components/react-table/library/src/components/DataGrid/DataGrid.types.ts
基础表格渲染示例:
<DataGrid>
<DataGridHeader>
<DataGridRow>
<DataGridHeaderCell>ID</DataGridHeaderCell>
<DataGridHeaderCell>名称</DataGridHeaderCell>
<DataGridHeaderCell>状态</DataGridHeaderCell>
</DataGridRow>
</DataGridHeader>
<DataGridBody>
{items.map(item => (
<DataGridRow key={item.id}>
<DataGridCell>{item.id}</DataGridCell>
<DataGridCell>{item.name}</DataGridCell>
<DataGridCell>{item.status}</DataGridCell>
</DataGridRow>
))}
</DataGridBody>
</DataGrid>
客户端分页实现
状态管理
使用React hooks管理分页状态:
const [currentPage, setCurrentPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const totalItems = items.length;
const totalPages = Math.ceil(totalItems / pageSize);
数据切片处理
实现客户端数据分页逻辑:
const paginatedItems = useMemo(() => {
const startIndex = (currentPage - 1) * pageSize;
return items.slice(startIndex, startIndex + pageSize);
}, [items, currentPage, pageSize]);
分页控制器组件
结合Fluent UI的Pagination组件:
import { Pagination } from '@fluentui/react-components';
<Pagination
currentPage={currentPage}
totalPages={totalPages}
onPageChange={(_, data) => setCurrentPage(data.currentPage)}
pageSize={pageSize}
onPageSizeChange={(_, data) => {
setPageSize(data.pageSize);
setCurrentPage(1); // 重置到第一页
}}
pageSizeOptions={[5, 10, 20, 50]}
/>
完整实现参考:packages/react-components/react-table/stories/src/DataGrid/ResizableColumns.stories.tsx
服务器端分页实现
API交互设计
定义分页请求参数接口:
interface PaginationParams {
pageNumber: number;
pageSize: number;
sortBy?: string;
sortDirection?: 'asc' | 'desc';
}
// 分页响应结构
interface PaginatedResponse<T> {
data: T[];
totalCount: number;
pageNumber: number;
pageSize: number;
}
数据获取逻辑
实现带分页参数的API请求:
const fetchData = useCallback(async (params: PaginationParams) => {
setLoading(true);
try {
const response = await apiClient.get('/items', { params });
setItems(response.data.data);
setTotalItems(response.data.totalCount);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
}, []);
// 页面变化时重新获取数据
useEffect(() => {
fetchData({ pageNumber: currentPage, pageSize });
}, [currentPage, pageSize, fetchData]);
加载状态处理
添加加载状态指示器:
import { Skeleton } from '@fluentui/react-components';
<DataGridBody>
{loading ? (
// 渲染骨架屏
Array.from({ length: pageSize }).map((_, index) => (
<DataGridRow key={`loading-${index}`}>
<DataGridCell><Skeleton height={20} /></DataGridCell>
<DataGridCell><Skeleton height={20} width={150} /></DataGridCell>
<DataGridCell><Skeleton height={20} width={80} /></DataGridCell>
</DataGridRow>
))
) : (
// 渲染实际数据
paginatedItems.map(item => (
<DataGridRow key={item.id}>
{/* 单元格内容 */}
</DataGridRow>
))
)}
</DataGridBody>
高级功能实现
排序与分页结合
实现排序状态下的分页保持:
const [sortConfig, setSortConfig] = useState({ key: 'id', direction: 'asc' });
useEffect(() => {
fetchData({
pageNumber: currentPage,
pageSize,
sortBy: sortConfig.key,
sortDirection: sortConfig.direction
});
}, [currentPage, pageSize, sortConfig]);
记忆化优化
使用useMemo和useCallback优化性能:
// 记忆化排序函数
const sortedItems = useMemo(() => {
return [...items].sort((a, b) => {
if (a[sortConfig.key] < b[sortConfig.key]) {
return sortConfig.direction === 'asc' ? -1 : 1;
}
// 排序逻辑...
});
}, [items, sortConfig]);
最佳实践与性能优化
-
虚拟滚动:处理超大数据集时,结合
react-virtualized或react-window参考:packages/react-components/deprecated/react-virtualizer/ -
分页状态持久化:使用URL参数保存分页状态
// 从URL获取初始分页参数 useEffect(() => { const searchParams = new URLSearchParams(window.location.search); const page = Number(searchParams.get('page')) || 1; const size = Number(searchParams.get('pageSize')) || 10; setCurrentPage(page); setPageSize(size); }, []); -
批量操作处理:客户端分页时注意勾选状态跨页保持
常见问题解决方案
数据闪烁问题
使用稳定的key和React.memo避免不必要的重渲染:
const MemoizedDataGridRow = React.memo(DataGridRow);
大数据性能优化
当客户端数据超过500条时,考虑:
- 实现虚拟列表
- 增加数据缓存策略
- 考虑迁移至服务器端分页
总结
Fluent UI提供了灵活的表格组件架构,使分页实现变得简单高效。客户端分页适用于小规模数据展示,实现简单且交互流畅;服务器端分页则适合处理大规模数据集,需注意网络状态管理和加载优化。
完整示例代码可参考:
通过合理选择分页策略并结合Fluent UI的组件能力,可以构建出高性能、用户友好的数据表格应用。
【免费下载链接】fluentui 项目地址: https://gitcode.com/GitHub_Trending/of/fluentui
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



