Browse Source

历史数据需要优化,需要流加载的方式 ,生成md 记录

release/web-ui-v1.0.0
root 4 months ago
parent
commit
dffc8c2e54
  1. 238
      src/HistoryProtocolLogsView_InfiniteScroll_Implementation.md

238
src/HistoryProtocolLogsView_InfiniteScroll_Implementation.md

@ -0,0 +1,238 @@
# HistoryProtocolLogsView 流式加载功能实现
## 修改时间
2025-01-27
## 修改文件
`X1.WebUI/src/pages/protocol-logs/HistoryProtocolLogsView.tsx`
## 修改目标
为 HistoryProtocolLogsView 组件添加流式加载(infinite scroll)功能,使用 IntersectionObserver 实现,支持分页加载和用户友好的交互体验。
## 修改内容
### 1. 组件接口更新
- 添加 `HistoryProtocolLogsViewProps` 接口,支持可选的 `fetchData` props
- 提供默认的数据获取函数 `defaultFetchData`,保持向后兼容性
- 使用传入的 `fetchData` 或默认函数进行数据加载
### 2. 状态管理增强
- 添加 `currentPage` 状态管理当前页码
- 添加 `hasMore` 状态标识是否还有更多数据
- 添加 `loadingMore` 状态管理加载更多数据的状态
- 添加 `isInitialLoad` 状态区分初始加载和后续加载
### 3. IntersectionObserver 实现
- 使用 `useRef` 创建观察器引用 `observerRef`
- 使用 `useCallback` 优化 `loadMoreData` 函数
- 设置观察器选项:`rootMargin: '100px'` 提前100px开始加载
- 在 `useEffect` 中设置和清理观察器
### 4. 数据加载逻辑
- 实现 `loadMoreData` 函数,处理分页数据加载
- 支持数据追加:`setProtocolLogs(prev => [...prev, ...newData])`
- 自动更新页码:`setCurrentPage(prev => prev + 1)`
- 检测数据结束:根据返回数据量判断是否还有更多数据
### 5. 用户界面优化
- 添加加载更多提示:显示"加载更多数据..."状态
- 添加数据结束提示:显示"已加载全部数据"
- 更新记录数显示:包含"滚动加载更多"提示
- 添加加载状态图标:使用 `Loader2` 组件
### 6. 错误处理
- 完整的错误捕获和用户提示
- 使用 Toast 组件显示错误信息
- 保持加载状态的一致性
## 技术特性
### IntersectionObserver 配置
```typescript
const observer = new IntersectionObserver(
(entries) => {
const [entry] = entries;
if (entry.isIntersecting && hasMore && !loadingMore) {
loadMoreData();
}
},
{
root: null,
rootMargin: '100px', // 提前100px开始加载
threshold: 0.1,
}
);
```
### 数据加载函数
```typescript
const loadMoreData = useCallback(async () => {
if (loadingMore || !hasMore) return;
setLoadingMore(true);
try {
const newData = await fetchDataFunction(currentPage + 1);
if (newData.length > 0) {
setProtocolLogs(prev => [...prev, ...newData]);
setCurrentPage(prev => prev + 1);
} else {
setHasMore(false);
}
} catch (error) {
// 错误处理
} finally {
setLoadingMore(false);
}
}, [currentPage, hasMore, loadingMore, fetchDataFunction, toast]);
```
### 默认数据获取函数
```typescript
const defaultFetchData = async (page: number): Promise<ProtocolLogDto[]> => {
const requestParams = {
...searchParams,
page,
pageSize: 20, // 每页20条记录
};
const result = await protocolLogsService.getProtocolLogs(requestParams);
if (result.isSuccess && result.data) {
return result.data.items || [];
} else {
throw new Error(result.errorMessages?.join(', ') || '获取数据失败');
}
};
```
## 使用示例
### 使用默认数据获取
```typescript
<HistoryProtocolLogsView />
```
### 使用自定义数据获取函数
```typescript
<HistoryProtocolLogsView
fetchData={async (page) => {
const result = await customApi.getProtocolLogs({ page, pageSize: 20 });
return result.data.items || [];
}}
/>
```
## 功能效果
### 用户体验改进
- ✅ **平滑滚动加载**:用户滚动到页面底部时自动加载更多数据
- ✅ **数据追加显示**:新数据追加到现有表格,不会影响现有数据的显示
- ✅ **加载状态反馈**:提供清晰的加载状态和进度提示
- ✅ **数据结束提示**:当没有更多数据时显示相应提示
- ✅ **错误处理**:完整的错误捕获和用户友好的错误提示
### 性能优化
- ✅ **IntersectionObserver**:使用现代浏览器API实现高效的滚动检测
- ✅ **useCallback 优化**:避免不必要的函数重创建
- ✅ **useRef 优化**:避免观察器重复创建
- ✅ **分页加载**:避免一次性加载大量数据导致的性能问题
### 向后兼容性
- ✅ **可选 props**:`fetchData` 为可选参数,不影响现有使用
- ✅ **默认行为**:保持原有的数据获取逻辑
- ✅ **接口兼容**:不破坏现有的组件接口
## 技术实现细节
### 观察器生命周期管理
```typescript
useEffect(() => {
if (!observerRef.current) return;
observer.current = new IntersectionObserver(/* ... */);
observer.current.observe(observerRef.current);
return () => {
if (observer.current) {
observer.current.disconnect();
}
};
}, [loadMoreData, hasMore, loadingMore]);
```
### 状态重置逻辑
```typescript
const fetchProtocolLogs = async (params: GetProtocolLogsRequest = searchParams) => {
setLoading(true);
setIsInitialLoad(true);
setCurrentPage(1);
setHasMore(true);
// ... 数据加载逻辑
};
```
### 用户界面元素
```typescript
{/* 无限滚动观察器 */}
{hasMore && (
<div ref={observerRef} className="flex justify-center items-center py-4">
{loadingMore && (
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<Loader2 className="h-4 w-4 animate-spin" />
加载更多数据...
</div>
)}
</div>
)}
{/* 没有更多数据的提示 */}
{!hasMore && protocolLogs.length > 0 && !isInitialLoad && (
<div className="flex justify-center items-center py-4">
<span className="text-sm text-muted-foreground">
已加载全部数据
</span>
</div>
)}
```
## 测试建议
### 功能测试
1. **基本滚动加载**:测试滚动到底部时是否自动加载更多数据
2. **数据追加**:验证新数据是否正确追加到现有表格
3. **加载状态**:检查加载状态是否正确显示和隐藏
4. **数据结束**:测试当没有更多数据时的提示显示
5. **错误处理**:测试网络错误时的错误提示
### 性能测试
1. **大量数据**:测试加载大量数据时的性能表现
2. **内存使用**:检查长时间使用时的内存占用
3. **滚动性能**:验证滚动时的流畅度
### 兼容性测试
1. **浏览器兼容性**:测试不同浏览器对 IntersectionObserver 的支持
2. **移动端适配**:验证在移动设备上的使用体验
3. **响应式设计**:测试不同屏幕尺寸下的显示效果
## 后续优化建议
### 可能的改进方向
1. **虚拟滚动**:对于超大数据量,考虑实现虚拟滚动
2. **缓存机制**:添加数据缓存,避免重复加载
3. **预加载**:实现预加载机制,提前加载下一页数据
4. **搜索重置**:搜索时重置分页状态
5. **加载动画**:添加更丰富的加载动画效果
### 监控指标
1. **加载成功率**:监控数据加载的成功率
2. **加载时间**:监控每次加载的耗时
3. **用户行为**:监控用户的滚动和加载行为
4. **错误率**:监控加载错误的频率
## 总结
本次修改成功为 HistoryProtocolLogsView 组件添加了流式加载功能,提供了良好的用户体验和性能表现。实现采用了现代的 IntersectionObserver API,确保了高效的滚动检测和流畅的用户交互。同时保持了向后兼容性,不影响现有功能的使用。
该实现为后续的大数据量展示需求提供了良好的基础,可以根据实际使用情况进行进一步的优化和扩展。
Loading…
Cancel
Save