diff --git a/web/src/views/Home.vue b/web/src/views/Home.vue index 8745332..0ab29a7 100644 --- a/web/src/views/Home.vue +++ b/web/src/views/Home.vue @@ -145,13 +145,13 @@ > {{ item.label }} @@ -333,6 +333,15 @@ import { getCachedWebSiteId, fetchWebRoutes } from '../api/webPages' const socialFollowItems = PROMOTION_SOCIAL_FOLLOW +/** 「关注我们」列表图标:必须用响应式候选下标驱动 :src,勿在 @error 里只改 DOM,否则重渲染会回到 candidates[0] 裂图 */ +const socialListImgIdx = reactive(Object.fromEntries(PROMOTION_SOCIAL_FOLLOW.map((x) => [x.id, 0]))) +function socialListImgSrc(item) { + const list = item.imageCandidates || [] + if (!list.length) return '' + const i = Math.min(socialListImgIdx[item.id] ?? 0, list.length - 1) + return list[i] +} + const starsEl = ref(null) let cometTimer = null const scrollY = ref(0) @@ -539,9 +548,11 @@ function closeVideoModal() { function openSocialFollow(item) { socialQrTitle.value = item.label - socialQrCandidates.value = item.imageCandidates || [] - socialQrCandidateIdx.value = 0 - socialQrImage.value = item.imageCandidates?.[0] || '' + const list = item.imageCandidates || [] + socialQrCandidates.value = list + const start = Math.min(socialListImgIdx[item.id] ?? 0, Math.max(0, list.length - 1)) + socialQrCandidateIdx.value = start + socialQrImage.value = list[start] || '' socialQrHref.value = item.href || '' socialQrOpen.value = true } @@ -554,14 +565,12 @@ function closeSocialFollow() { socialQrCandidateIdx.value = 0 } -/** public /social、public 根路径无图时依次尝试 /promotion/social/ */ -function onSocialFollowListImgError(e, item) { - const img = e.target +/** 当前候选 404/裂图时换下一 URL(与 :src 绑定同一套下标,避免被 Vue 刷回) */ +function onSocialFollowListImgError(item) { const list = item.imageCandidates || [] - let i = Number(img.dataset.fi || 0) + const i = socialListImgIdx[item.id] ?? 0 if (i + 1 < list.length) { - img.dataset.fi = String(i + 1) - img.src = list[i + 1] + socialListImgIdx[item.id] = i + 1 } }