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

之前的问题:

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

  现在的方案:

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

View File

@@ -343,64 +343,63 @@ 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}
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 <EventScrollList
// 2. 有数据或有缓存 → 显示列表 events={currentPageEvents}
// 3. 无数据且未加载 → 显示空状态 displayEvents={displayEvents} // 累积显示的事件列表(平铺模式)
loadNextPage={loadNextPage} // 加载下一页
if (loading) { loadPrevPage={loadPrevPage} // 加载上一页
/* 首次加载状态 - 无缓存数据时显示 loading */ onFourRowEventClick={handleFourRowEventClick} // 四排模式事件点击
return ( selectedEvent={selectedEvent}
<Center py={10}> onEventSelect={setSelectedEvent}
<VStack> borderColor={borderColor}
<Spinner size="xl" color="blue.500" thickness="4px" /> currentPage={currentPage}
<Text color="gray.500">正在加载最新事件...</Text> totalPages={totalPages}
</VStack> onPageChange={handlePageChange}
</Center> loading={loadingPage !== null}
); loadingPage={loadingPage}
} else if (currentPageEvents.length > 0 || hasCachedData) { error={error}
/* 有数据 - 显示列表(可能在后台加载下一页) */ mode={mode}
return ( onModeChange={handleModeToggle}
<EventScrollList eventFollowStatus={eventFollowStatus}
events={currentPageEvents} onToggleFollow={handleToggleFollow}
displayEvents={displayEvents} // 累积显示的事件列表(平铺模式) hasMore={hasMore}
loadNextPage={loadNextPage} // 加载下一页 />
loadPrevPage={loadPrevPage} // 加载上一页 </Box>
onFourRowEventClick={handleFourRowEventClick} // 四排模式事件点击 {/* 底部:分页控制器(仅在纵向模式显示) */}
selectedEvent={selectedEvent} {mode === 'vertical' && totalPages > 1 && (
onEventSelect={setSelectedEvent} <PaginationControl
borderColor={borderColor} currentPage={currentPage}
currentPage={currentPage} totalPages={totalPages}
totalPages={totalPages} onPageChange={handlePageChange}
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>
);
}
})()}
</CardBody> </CardBody>
{/* 四排模式详情弹窗 - 未打开时不渲染 */} {/* 四排模式详情弹窗 - 未打开时不渲染 */}