fix(web): 关注我们列表图用响应式候选下标,避免重渲染覆盖 @error 导致裂图

Made-with: Cursor
This commit is contained in:
whm
2026-03-22 01:45:03 +08:00
parent 948494bca0
commit 6f87e0c260

View File

@@ -145,13 +145,13 @@
> >
<span class="social-pill-icon-wrap"> <span class="social-pill-icon-wrap">
<img <img
:src="item.imageCandidates[0]" :src="socialListImgSrc(item)"
:alt="item.label" :alt="item.label"
class="social-pill-icon" class="social-pill-icon"
width="32" width="32"
height="32" height="32"
loading="lazy" loading="lazy"
@error="(e) => onSocialFollowListImgError(e, item)" @error="onSocialFollowListImgError(item)"
/> />
</span> </span>
<span class="social-pill-label">{{ item.label }}</span> <span class="social-pill-label">{{ item.label }}</span>
@@ -333,6 +333,15 @@ import { getCachedWebSiteId, fetchWebRoutes } from '../api/webPages'
const socialFollowItems = PROMOTION_SOCIAL_FOLLOW 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) const starsEl = ref(null)
let cometTimer = null let cometTimer = null
const scrollY = ref(0) const scrollY = ref(0)
@@ -539,9 +548,11 @@ function closeVideoModal() {
function openSocialFollow(item) { function openSocialFollow(item) {
socialQrTitle.value = item.label socialQrTitle.value = item.label
socialQrCandidates.value = item.imageCandidates || [] const list = item.imageCandidates || []
socialQrCandidateIdx.value = 0 socialQrCandidates.value = list
socialQrImage.value = item.imageCandidates?.[0] || '' 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 || '' socialQrHref.value = item.href || ''
socialQrOpen.value = true socialQrOpen.value = true
} }
@@ -554,14 +565,12 @@ function closeSocialFollow() {
socialQrCandidateIdx.value = 0 socialQrCandidateIdx.value = 0
} }
/** public /social、public 根路径无图时依次尝试 /promotion/social/ */ /** 当前候选 404/裂图时换下一 URL与 :src 绑定同一套下标,避免被 Vue 刷回) */
function onSocialFollowListImgError(e, item) { function onSocialFollowListImgError(item) {
const img = e.target
const list = item.imageCandidates || [] const list = item.imageCandidates || []
let i = Number(img.dataset.fi || 0) const i = socialListImgIdx[item.id] ?? 0
if (i + 1 < list.length) { if (i + 1 < list.length) {
img.dataset.fi = String(i + 1) socialListImgIdx[item.id] = i + 1
img.src = list[i + 1]
} }
} }