feat: 从替换式渲染 → 蒙层式渲染
之前的问题: - Loading 时替换整个列表组件 - 组件频繁挂载/卸载,性能差 - 切换模式时界面跳动明显 现在的方案: - ✅ 列表组件始终渲染(避免频繁挂载卸载) - ✅ Loading 通过蒙层叠加显示 - ✅ 旧数据保持可见直到新数据加载完成 - ✅ 更平滑的视觉过渡
This commit is contained in:
@@ -343,64 +343,63 @@ const DynamicNewsCard = forwardRef(({
|
||||
)}
|
||||
</Flex>
|
||||
|
||||
{/* 横向滚动事件列表 - 根据数据情况渲染 */}
|
||||
{(() => {
|
||||
// 检查对应模式是否有缓存数据(使用 mode 而非 currentMode,避免延迟)
|
||||
const hasCachedData = mode === 'vertical'
|
||||
? Object.keys(allCachedEventsByPage || {}).length > 0
|
||||
: (allCachedEvents?.length || 0) > 0;
|
||||
{/* 横向滚动事件列表 - 始终渲染 + Loading 蒙层 */}
|
||||
<Box position="relative">
|
||||
{/* Loading 蒙层 - 数据请求时显示 */}
|
||||
{loading && (
|
||||
<Box
|
||||
position="absolute"
|
||||
top={0}
|
||||
left={0}
|
||||
right={0}
|
||||
bottom={0}
|
||||
bg={useColorModeValue('rgba(255, 255, 255, 0.85)', 'rgba(26, 32, 44, 0.85)')}
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
zIndex={10}
|
||||
borderRadius="md"
|
||||
>
|
||||
<VStack spacing={3}>
|
||||
<Spinner size="xl" color="blue.500" thickness="4px" />
|
||||
<Text color={useColorModeValue('gray.600', 'gray.300')} fontWeight="medium">
|
||||
正在加载最新事件...
|
||||
</Text>
|
||||
</VStack>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
// 【优化渲染顺序】优先判断 loading,避免闪现空状态
|
||||
// 1. 首次加载(无缓存 + 加载中)→ 显示 loading
|
||||
// 2. 有数据或有缓存 → 显示列表
|
||||
// 3. 无数据且未加载 → 显示空状态
|
||||
|
||||
if (loading) {
|
||||
/* 首次加载状态 - 无缓存数据时显示 loading */
|
||||
return (
|
||||
<Center py={10}>
|
||||
<VStack>
|
||||
<Spinner size="xl" color="blue.500" thickness="4px" />
|
||||
<Text color="gray.500">正在加载最新事件...</Text>
|
||||
</VStack>
|
||||
</Center>
|
||||
);
|
||||
} else if (currentPageEvents.length > 0 || hasCachedData) {
|
||||
/* 有数据 - 显示列表(可能在后台加载下一页) */
|
||||
return (
|
||||
<EventScrollList
|
||||
events={currentPageEvents}
|
||||
displayEvents={displayEvents} // 累积显示的事件列表(平铺模式)
|
||||
loadNextPage={loadNextPage} // 加载下一页
|
||||
loadPrevPage={loadPrevPage} // 加载上一页
|
||||
onFourRowEventClick={handleFourRowEventClick} // 四排模式事件点击
|
||||
selectedEvent={selectedEvent}
|
||||
onEventSelect={setSelectedEvent}
|
||||
borderColor={borderColor}
|
||||
currentPage={currentPage}
|
||||
totalPages={totalPages}
|
||||
onPageChange={handlePageChange}
|
||||
loading={loadingPage !== null}
|
||||
loadingPage={loadingPage}
|
||||
error={error}
|
||||
mode={mode}
|
||||
onModeChange={handleModeToggle}
|
||||
eventFollowStatus={eventFollowStatus}
|
||||
onToggleFollow={handleToggleFollow}
|
||||
hasMore={hasMore}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
/* 空状态 - 确实无数据时才显示 */
|
||||
return (
|
||||
<Center py={10}>
|
||||
<VStack>
|
||||
<Text fontSize="lg" color="gray.500">暂无事件数据</Text>
|
||||
</VStack>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
})()}
|
||||
{/* 列表内容 - 始终渲染 */}
|
||||
<EventScrollList
|
||||
events={currentPageEvents}
|
||||
displayEvents={displayEvents} // 累积显示的事件列表(平铺模式)
|
||||
loadNextPage={loadNextPage} // 加载下一页
|
||||
loadPrevPage={loadPrevPage} // 加载上一页
|
||||
onFourRowEventClick={handleFourRowEventClick} // 四排模式事件点击
|
||||
selectedEvent={selectedEvent}
|
||||
onEventSelect={setSelectedEvent}
|
||||
borderColor={borderColor}
|
||||
currentPage={currentPage}
|
||||
totalPages={totalPages}
|
||||
onPageChange={handlePageChange}
|
||||
loading={loadingPage !== null}
|
||||
loadingPage={loadingPage}
|
||||
error={error}
|
||||
mode={mode}
|
||||
onModeChange={handleModeToggle}
|
||||
eventFollowStatus={eventFollowStatus}
|
||||
onToggleFollow={handleToggleFollow}
|
||||
hasMore={hasMore}
|
||||
/>
|
||||
</Box>
|
||||
{/* 底部:分页控制器(仅在纵向模式显示) */}
|
||||
{mode === 'vertical' && totalPages > 1 && (
|
||||
<PaginationControl
|
||||
currentPage={currentPage}
|
||||
totalPages={totalPages}
|
||||
onPageChange={handlePageChange}
|
||||
/>
|
||||
)}
|
||||
</CardBody>
|
||||
|
||||
{/* 四排模式详情弹窗 - 未打开时不渲染 */}
|
||||
|
||||
Reference in New Issue
Block a user