uni.previewImage的current参数必须为数字索引而非图片路径字符串,否则H5端失效、小程序端行为不可靠;urls须为纯字符串一维数组,current需在0到urls.length-1范围内并提前校验。

uni.previewImage 传参错位导致预览卡死第一张
点开预览只显示一张图,不是 bug 是误用。核心问题出在 current 参数:它必须是数字索引(比如 2),而不是图片路径字符串(比如 '/tmp/a.jpg')。H5 端完全不认路径字符串,小程序端部分版本虽能 fallback 到第一张,但行为不可靠。
常见错误写法:
uni.previewImage({
current: this.selectedImages[index], // ❌ 错!这是路径
urls: this.selectedImages
})
正确做法是先确保 urls 是纯字符串数组,再传对应下标:
-
urls必须是形如['/a.jpg', '/b.png']的一维数组,不能含null、undefined或嵌套对象 - 如果
selectedImages是对象数组(如{ path: '/a.jpg', id: '1' }),得先提取:const urls = this.selectedImages.map(img => img.path) -
current必须是number类型,且在0到urls.length - 1范围内;预览前建议加校验:if (index >= 0 && index
删除图片后预览索引失效怎么办
用户删掉第 2 张图后还在滑动预览,结果跳到白屏或错图——本质是 UI 状态(当前滑动位置)和数据状态(已删图的数组)脱节。
别指望 uni.previewImage 自动感知数组变化。它只认你传进去的那一刻的 urls 和 current。
- 最稳妥方案:删除后立刻关闭预览框,设
this.previewVisible = false(如果你用自定义组件)或直接不调用uni.previewImage - 若坚持保留预览态,需手动重算
current:删图前记录被删项的path或id,删完后遍历新数组找它的新下标,再调用uni.previewImage并传新索引 - 避免用
splice(index, 1)后还沿用原index作为current,尤其当index接近末尾时,极易越界
用自定义组件替代 uni.previewImage 实现风格可控
uni.previewImage 样式完全不可控,指示器位置、关闭按钮、缩放手势全由平台决定。要自定义风格(比如顶部带标题、右上角删除按钮、底部操作栏),必须自己实现预览层。
关键点:
- 用
+搭建轮播容器,current绑定到 data 中的索引变量,可双向控制 - 点击删除按钮时,触发子组件事件(如
@delete="onDeleteInPreview"),父组件收到后执行删除逻辑,并同步更新current(比如删的是当前页,就current = Math.max(0, current - 1)) - 禁用原生缩放(
mode="aspectFill")、隐藏滚动条、监听touchstart防止穿透到下层 - 注意 H5 端
swiper的duration和interval表现差异,安卓低端机慎用change:current频繁触发
删除按钮点击无响应的三个高频原因
预览中点击 × 没反应,90% 不是逻辑问题,而是事件绑定或层级问题。
- 没加
@stop或@prevent:,否则点击会冒泡触发 swiper 切页× - z-index 被盖住:自定义预览层里,删除按钮的
z-index必须高于image和swiper-item,推荐设为999 - 按钮在
swiper-item外层:必须把删除按钮放在每个swiper-item内部,否则无法精准定位当前页要删哪张
真正难处理的,是删除后还要维持“正在预览第 N 张”的连贯感——这要求你在数据变更、UI 更新、索引重算三者间做精确时序控制,稍有延迟就会出现闪一下再跳走的现象。











