diff --git a/src/views/Activities/WorldCup/EventDetail/index.vue b/src/views/Activities/WorldCup/EventDetail/index.vue index 89744c2..9a0addc 100644 --- a/src/views/Activities/WorldCup/EventDetail/index.vue +++ b/src/views/Activities/WorldCup/EventDetail/index.vue @@ -758,16 +758,22 @@ const loadMyBetList = async () => { myBets.value = records } -// 页面初始化:遵循建页规则,预加载关键图片并拉取详情与我的竞猜记录后再关闭 loading。 -const completePreloading = async () => { +// 页面初始化接口:连接 App 并写入请求头后,再独立拉取赛事详情和我的竞猜记录。 +const loadInitialEventDetailData = async () => { try { - await Promise.all([ - preloadImages(blockingImages.map((imageName) => pngUrl(imageName))), - loadMatchDetail(), - ]) + await loadMatchDetail() await loadMyBetList() } catch (error) { console.error('WorldCup 赛事详情加载失败:', error) + } +} + +// 首屏预加载:只处理阻塞图片,不等待接口数据返回。 +const completePreloading = async () => { + try { + await preloadImages(blockingImages.map((imageName) => pngUrl(imageName))) + } catch (error) { + console.error('WorldCup 赛事详情图片预加载失败:', error) } finally { isLoading.value = false } @@ -776,7 +782,7 @@ const completePreloading = async () => { // 连接 App 并设置接口请求头:详情页所有接口请求必须在 connectToApp 成功后执行。 const connectToAppHandler = async () => { await connectToApp(() => { - completePreloading() + loadInitialEventDetailData() }) } @@ -817,6 +823,7 @@ onMounted(() => { countdownTimer = window.setInterval(() => { nowTime.value = Date.now() }, 1000) + completePreloading() connectToAppHandler() }) diff --git a/src/views/Activities/WorldCup/EventDetail/页面创建信息.md b/src/views/Activities/WorldCup/EventDetail/页面创建信息.md index bfd230f..133fe9a 100644 --- a/src/views/Activities/WorldCup/EventDetail/页面创建信息.md +++ b/src/views/Activities/WorldCup/EventDetail/页面创建信息.md @@ -7,9 +7,9 @@ - 页面模块、div 结构、方法、接口处理都需要补充中文注释。 - 页面根容器使用 `100vh` 方案,内部滚动并隐藏滚动条,不展示可见滚动条。 - 能使用内联样式处理的页面样式,优先使用内联样式。 -- 新建或更新 `index.vue` 时必须使用统一加载动画:`isLoading` 阶段只渲染 `LoadingContent`,关键图片和初始化接口完成后再渲染正式背景图与业务节点。 +- 新建或更新 `index.vue` 时必须使用统一加载动画:`isLoading` 阶段只渲染 `LoadingContent`,阻塞图片预加载完成后再渲染正式背景图与业务节点;业务接口不参与 loading 阻塞。 - 普通业务模块不提前设置 `min-height` 和 `line-height`;`min-height` 只在基础页面容器按需使用,`itemCenter` 的 `min-height` 只在页面开发完成后确实需要稳定图片容器高度时再补。 -- 页面使用接口前必须先调用 `connectToApp` 设置请求头;当前详情页通过 `connectToAppHandler()` 包裹 `completePreloading()`,赛事详情和我的竞猜记录接口都在连接成功后请求。 +- 页面使用接口前必须先调用 `connectToApp` 设置请求头;当前详情页的 `completePreloading()` 只负责阻塞图片预加载并控制 loading,赛事详情和我的竞猜记录接口已提取到 `loadInitialEventDetailData()`,在 `connectToAppHandler()` 连接成功后独立请求。 ## 1. 基础信息 diff --git a/src/views/Activities/WorldCup/index.vue b/src/views/Activities/WorldCup/index.vue index 5cae33e..c6e2f84 100644 --- a/src/views/Activities/WorldCup/index.vue +++ b/src/views/Activities/WorldCup/index.vue @@ -395,8 +395,11 @@ " > - - + - + @@ -1703,16 +1710,17 @@ const handleCloseRulePopup = () => { showRulePopup.value = false } -// 首屏图片、排行榜和赛事数据一起完成后再关闭 loading。 +// 页面初始化接口:连接 App 并写入请求头后,再独立拉取排行榜和默认赛事列表。 +const loadInitialWorldCupData = async () => { + await Promise.all([getPersonalRanking(), getWorldCupMatchList()]) +} + +// 首屏预加载:只处理阻塞图片,不等待接口数据返回。 const completePreloading = async () => { try { - await Promise.all([ - getPersonalRanking(), - getWorldCupMatchList(), - preloadImages(blockingImages.map((imageName) => pngUrl(imageName))), - ]) + await preloadImages(blockingImages.map((imageName) => pngUrl(imageName))) } catch (error) { - console.error('WorldCup 预加载过程中发生错误:', error) + console.error('WorldCup 图片预加载过程中发生错误:', error) } finally { isLoading.value = false } @@ -1721,11 +1729,12 @@ const completePreloading = async () => { // 连接 App 并设置接口请求头:所有业务接口必须在 connectToApp 成功后再请求。 const connectToAppHandler = async () => { await connectToApp(() => { - completePreloading() + loadInitialWorldCupData() }) } onMounted(() => { + completePreloading() connectToAppHandler() }) diff --git a/src/views/Activities/WorldCup/页面创建信息.md b/src/views/Activities/WorldCup/页面创建信息.md index 6ea5c8b..6701602 100644 --- a/src/views/Activities/WorldCup/页面创建信息.md +++ b/src/views/Activities/WorldCup/页面创建信息.md @@ -8,7 +8,7 @@ - 能使用内联样式处理的页面样式,优先使用内联样式。 - 页面根容器使用 `height: 100vh`,内部主内容垂直滚动并隐藏滚动条,页面任何模块都不展示可见滚动条。 - 接口返回的远程图片链接不要使用 `v-smart-img`,直接使用原生 `` 展示,不走本地图片缓存。 -- 页面使用接口前必须先调用 `connectToApp` 设置请求头;当前首页通过 `connectToAppHandler()` 包裹 `completePreloading()`,排行榜和赛事列表接口都在连接成功后请求。 +- 页面使用接口前必须先调用 `connectToApp` 设置请求头;当前首页的 `completePreloading()` 只负责阻塞图片预加载并控制 loading,排行榜和赛事列表接口已提取到 `loadInitialWorldCupData()`,在 `connectToAppHandler()` 连接成功后独立请求。 ## 1. 基础信息 @@ -74,7 +74,7 @@ `bg2`、`bg`、`ruleBt`、`ruleBg`、`EventlistBg`、`matchBg`、`drawSign`、`frameWinner`、`numPeople`、`rightBt`、`RankingMain`、`RankingItem`、`RankingBottomBorder`、`myRankingBg`、`giftBt`、`rewardBg`、`showMoreBt`、`frameTop1`、`frameTop2`、`frameTop3`、`vip1-vip6`、`userLevel1Bg-userLevel5Bg`、`wealthLevel1Bg-wealthLevel5Bg`。 -页面进入时必须展示统一加载动画,阻塞预加载完成后再展示主内容。 +页面进入时必须展示统一加载动画,阻塞图片预加载完成后再展示主内容;业务接口不参与 loading 阻塞。 ### 3.3 itemCenter 高度约束 @@ -143,6 +143,7 @@ - 每次切换按钮都重新发送接口,暂不做上拉加载。 - 两个 tab 的数据必须分开承载:`predictMatchList` 保存 Predict Now 数据,`endedMatchList` 保存 Ended 数据,避免接口慢返回时两个列表数据混用。 - 请求保护使用每个 tab 独立的 request token:只忽略同 tab 内更旧的响应,不影响另一个 tab 的缓存。 +- 赛事列表两个 tab 的列表容器使用 `v-show` 保留 DOM,不使用 `v-if` 销毁重建;切换时仍重新请求接口获取最新数据,但固定图片如 `matchBg`、`numPeople`、`rightBt`、`drawSign` 不随 tab 切换反复重建加载。 - Predict Now 使用 `matchBg` 的 `itemCenter` 渲染列表项。 - Ended 不使用 `matchBg`,直接使用普通 `div` 卡片样式渲染列表项。 - Predict Now 和 Ended 的单条列表都使用新的 column wrapper:上方是原赛事卡片,下方是总奖池入口,用 `gap` 控制上下间距。