uni-app中swiper实现缩略图预览需控制加载时机与交互:仅渲染当前页及左右各一张,image用缩略图src+preview-src存原图,点击调用uni.previewimage;多图轮播含视频时须手动接管autoplay。

uni-app里用swiper做自定义轮播,别只靠默认样式
官方swiper组件本身不提供缩略图预览能力,但它的结构足够灵活,可以配合image的mode、懒加载逻辑和点击事件实现「缩略图占位 + 点击放大」的效果。关键不是替换swiper,而是控制它里面每张图的加载时机和交互行为。
常见错误是把所有高清图一股脑塞进swiper-item里,导致首屏卡顿、内存飙升,尤其在App端容易白屏或崩溃。
- 只在
swiper-item中渲染当前页 + 左右各一张(共三张),用v-if控制显隐,避免DOM堆积 - 每张
image的src设为缩略图地址,同时绑定preview-src(自定义属性)存原图URL - 给
image加@click="handlePreview(index)",点击时传入当前索引和preview-src数组 - H5端记得加
style="user-select: none",防止长按弹出菜单干扰手势
缩略图预览要真“懒”,得靠preview-src + uni.previewImage组合
Wot Design Uni 的preview-src只是个约定写法,uni-app原生并不识别它。你得自己在点击事件里构造预览参数——真正触发预览的是uni.previewImage,但它只接受图片 URL 数组,不关心哪张是缩略图。
所以缩略图预览的本质是:用户看到的是缩略图,点开后才用原图数组调起系统预览器。这中间没有“预览组件”,只有“预览动作”。
- 确保
preview-src数组里每个元素都是可直接访问的 HTTPS 图片地址(本地tempFilePath仅限 App 端,小程序/H5 不支持) - 调用前校验
current是否在数组长度范围内,否则滑动到边界会跳回第一张 - 如果想让当前点击图作为预览起点,传
current: index,不要传字符串 - 安卓真机上若预览空白,大概率是图片路径带空格或中文,需
encodeURIComponent编码
想支持手势缩放?uni.previewImage做不到,得自己封装
uni.previewImage在 iOS 和多数安卓 WebView 中默认禁用手势缩放,这不是 bug,是 WebView 安全策略限制。它底层没暴露 DOM 控制权,也没提供缩放回调。想实现微信那种双指放大+拖拽,必须另起炉灶。
核心思路是:用一个全屏view包裹image,监听touchstart/touchmove/touchend,通过transform: scale() translate()动态更新样式。难点不在逻辑,而在细节处理。
- 双指操作时,用
event.touches[0]和event.touches[1]算两指距离变化,驱动scale值 - 单指移动时,要基于上一次
scale值计算translateX/Y,否则缩放后拖拽会失准 - 缩放中心点必须是两指中点,不能固定屏幕中心,否则图像会偏移——要用
getBoundingClientRect()实时算相对位移 - H5端需加
touch-action: none禁用浏览器默认手势,否则和缩放冲突
多图混合轮播(图+视频)时,swiper的autoplay得手动接管
如果你的轮播里既有图片又有视频(比如旅游App首页),swiper自带的autoplay会强行推进,导致视频还没播完就被切走。这时候必须关掉原生自动播放,用定时器+状态判断来接管。
视频播放期间要暂停轮播,播放结束或用户点击才切下一张;切到图片时再恢复轮播。这个逻辑不能靠swiper自己完成,得靠ref拿到video实例,监听ended或play事件。
- 用
:autoplay="false"关闭swiper原生自动播放 - 维护一个
isVideoPlaying状态,在video的@play中置为true,@ended中置为false - 定时器里加判断:
if (!isVideoPlaying) { this.current++ } - 手动滑动时清掉旧定时器,滑动结束后重置并重启
swiper生命周期和video播放状态的耦合——这些地方不细抠,上线后就是白屏、卡顿、手势失效。











