feat: 从替换式渲染 → 蒙层式渲染

之前的问题:

  - Loading 时替换整个列表组件
  - 组件频繁挂载/卸载,性能差
  - 切换模式时界面跳动明显

  现在的方案:

  -  列表组件始终渲染(避免频繁挂载卸载)
  -  Loading 通过蒙层叠加显示
  -  旧数据保持可见直到新数据加载完成
  -  更平滑的视觉过渡
This commit is contained in:
zdl
2025-11-06 10:17:10 +08:00
parent 8eaaef1666
commit ca5adb3ad2

View File

@@ -343,31 +343,33 @@ const DynamicNewsCard = forwardRef(({
)} )}
</Flex> </Flex>
{/* 横向滚动事件列表 - 根据数据情况渲染 */} {/* 横向滚动事件列表 - 始终渲染 + Loading 蒙层 */}
{(() => { <Box position="relative">
// 检查对应模式是否有缓存数据(使用 mode 而非 currentMode避免延迟 {/* Loading 蒙层 - 数据请求时显示 */}
const hasCachedData = mode === 'vertical' {loading && (
? Object.keys(allCachedEventsByPage || {}).length > 0 <Box
: (allCachedEvents?.length || 0) > 0; position="absolute"
top={0}
// 【优化渲染顺序】优先判断 loading避免闪现空状态 left={0}
// 1. 首次加载(无缓存 + 加载中)→ 显示 loading right={0}
// 2. 有数据或有缓存 → 显示列表 bottom={0}
// 3. 无数据且未加载 → 显示空状态 bg={useColorModeValue('rgba(255, 255, 255, 0.85)', 'rgba(26, 32, 44, 0.85)')}
display="flex"
if (loading) { alignItems="center"
/* 首次加载状态 - 无缓存数据时显示 loading */ justifyContent="center"
return ( zIndex={10}
<Center py={10}> borderRadius="md"
<VStack> >
<VStack spacing={3}>
<Spinner size="xl" color="blue.500" thickness="4px" /> <Spinner size="xl" color="blue.500" thickness="4px" />
<Text color="gray.500">正在加载最新事件...</Text> <Text color={useColorModeValue('gray.600', 'gray.300')} fontWeight="medium">
正在加载最新事件...
</Text>
</VStack> </VStack>
</Center> </Box>
); )}
} else if (currentPageEvents.length > 0 || hasCachedData) {
/* 有数据 - 显示列表(可能在后台加载下一页) */ {/* 列表内容 - 始终渲染 */}
return (
<EventScrollList <EventScrollList
events={currentPageEvents} events={currentPageEvents}
displayEvents={displayEvents} // 累积显示的事件列表(平铺模式) displayEvents={displayEvents} // 累积显示的事件列表(平铺模式)
@@ -389,18 +391,15 @@ const DynamicNewsCard = forwardRef(({
onToggleFollow={handleToggleFollow} onToggleFollow={handleToggleFollow}
hasMore={hasMore} hasMore={hasMore}
/> />
); </Box>
} else { {/* 底部:分页控制器(仅在纵向模式显示) */}
/* 空状态 - 确实无数据时才显示 */ {mode === 'vertical' && totalPages > 1 && (
return ( <PaginationControl
<Center py={10}> currentPage={currentPage}
<VStack> totalPages={totalPages}
<Text fontSize="lg" color="gray.500">暂无事件数据</Text> onPageChange={handlePageChange}
</VStack> />
</Center> )}
);
}
})()}
</CardBody> </CardBody>
{/* 四排模式详情弹窗 - 未打开时不渲染 */} {/* 四排模式详情弹窗 - 未打开时不渲染 */}