From cd1e9ae488ff8486fafb2965d169a01ab63660af Mon Sep 17 00:00:00 2001 From: jacy <18049821889@163.com> Date: Mon, 17 Aug 2026 22:20:05 +0800 Subject: [PATCH] =?UTF-8?q?refactor(mini-user):=20=E9=97=A8=E5=BA=97?= =?UTF-8?q?=E5=A5=97=E9=A4=90=E5=9B=BE=E6=94=B9=E7=94=A8=20swiper=20auto-h?= =?UTF-8?q?eight=20=E8=87=AA=E9=80=82=E5=BA=94=EF=BC=88=E6=96=B9=E6=A1=88A?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除手算高度逻辑,自适应模式启用 swiper 原生 autoHeight - image 保持 mode=widthFix,完整展示不裁切 - 删除 .detail-carousel-wrap 固定比例/高度的覆盖依赖 Co-Authored-By: WorkBuddy --- .../src/components/ProductCarousel.tsx | 50 ++----------------- apps/mini-user/src/styles/product-detail.css | 10 ++-- 2 files changed, 7 insertions(+), 53 deletions(-) diff --git a/apps/mini-user/src/components/ProductCarousel.tsx b/apps/mini-user/src/components/ProductCarousel.tsx index 47f8a8c..23b22ad 100644 --- a/apps/mini-user/src/components/ProductCarousel.tsx +++ b/apps/mini-user/src/components/ProductCarousel.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useState } from 'react'; import { View, Image, Swiper, SwiperItem } from '@tarojs/components'; import Taro from '@tarojs/taro'; @@ -11,6 +11,7 @@ type ProductCarouselProps = { * cover=aspectFill 裁剪铺满(固定高度,可能裁切) * contain=aspectFit 完整显示(固定高度,可能留白) * adaptive=widthFix 按图片真实比例自适应高度,完整显示不裁剪(门店套餐详情用) + * 依赖 swiper 原生 auto-height:海报有多高,轮播就有多高,无裁切。 */ imageFit?: 'cover' | 'contain' | 'adaptive'; }; @@ -25,56 +26,12 @@ export default function ProductCarousel({ }: ProductCarouselProps) { const slides = images.length > 0 ? images : ['']; const [activeIndex, setActiveIndex] = useState(0); - // adaptive 模式:实测容器宽度与各图渲染高度 - const [wrapWidth, setWrapWidth] = useState(0); - const [imgHeights, setImgHeights] = useState([]); const prefix = variant === 'store' ? 'store-detail-carousel' : variant === 'home' ? 'home-carousel' : 'detail-carousel'; const isContain = imageFit === 'contain'; const isAdaptive = imageFit === 'adaptive'; const wrapClass = `${prefix}-wrap${isContain ? ` ${prefix}-wrap--contain` : ''}${isAdaptive ? ` ${prefix}-wrap--adaptive` : ''}`; - function getWindowWidth(): number { - try { - const info = (Taro as any).getWindowInfo?.() ?? Taro.getSystemInfoSync(); - return info?.windowWidth || 375; - } catch { - return 375; - } - } - - useEffect(() => { - if (!isAdaptive) return; - const query = Taro.createSelectorQuery(); - query - .select(`.${prefix}-wrap--adaptive`) - .boundingClientRect((rect: { width?: number }) => { - if (rect && rect.width) setWrapWidth(rect.width); - else setWrapWidth(getWindowWidth()); - }) - .exec(); - // 仅挂载时测量一次容器宽度(页面宽度稳定) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [isAdaptive, prefix]); - - function handleImageLoad(index: number, e: any) { - const detail = e?.detail; - const naturalW = detail?.width; - const naturalH = detail?.height; - if (!naturalW || !naturalH) return; - const w = wrapWidth || getWindowWidth(); - const h = Math.round((naturalH / naturalW) * w); - setImgHeights((prev) => { - const next = [...prev]; - next[index] = h; - return next; - }); - } - - // adaptive:随当前幻灯片高度变化;未加载时给一个 3:4 兜底高度 - const adaptiveHeight = imgHeights[activeIndex] || Math.round((wrapWidth || getWindowWidth()) * 0.75); - const swiperStyle = isAdaptive ? { height: `${adaptiveHeight}px` } : undefined; - function previewAt(index: number) { const urls = slides.filter(Boolean); if (!urls.length) return; @@ -86,8 +43,8 @@ export default function ProductCarousel({ 1} + autoHeight={isAdaptive} {...(variant === 'detail' && slides.length > 1 ? { autoplay: true, interval: 3500 } : {})} onChange={(e) => setActiveIndex(e.detail.current)} > @@ -99,7 +56,6 @@ export default function ProductCarousel({ src={src} mode={isAdaptive ? 'widthFix' : isContain ? 'aspectFit' : 'aspectFill'} alt={alt} - onLoad={isAdaptive ? (e) => handleImageLoad(index, e) : undefined} onClick={previewable ? () => previewAt(index) : undefined} /> ) : ( diff --git a/apps/mini-user/src/styles/product-detail.css b/apps/mini-user/src/styles/product-detail.css index cb2d3fa..41dbd51 100644 --- a/apps/mini-user/src/styles/product-detail.css +++ b/apps/mini-user/src/styles/product-detail.css @@ -18,17 +18,15 @@ overflow: hidden; } -/* adaptive 模式:去掉固定 1:1 比例,按图片真实比例自适应高度,完整显示不裁剪 */ +/* adaptive 模式(方案 A):删除固定 1:1 比例与固定高度, + 改用 swiper 原生 auto-height + image widthFix,海报有多高轮播就有多高,无裁切 */ .detail-carousel-wrap--adaptive { aspect-ratio: auto; overflow: visible; } -.detail-carousel-wrap--adaptive .detail-carousel { - height: auto; - transition: height 0.2s ease; -} - +.detail-carousel-wrap--adaptive .detail-carousel, +.detail-carousel-wrap--adaptive .detail-carousel-item, .detail-carousel-wrap--adaptive .detail-carousel-image { height: auto; }