uni.previewImage 白屏或跳图因 current 路径与更新后 imageList 不匹配,需删除前记录被删项 path,删后用 findIndex 重算索引,未找到则关闭预览;sizeType 推荐仅用 ['compressed'] 配合按需压缩防 OOM;自定义组件须监听 imageList 变化同步 urls 和 current;删除按钮应 pointer-events: none 确保点击穿透。

uni.previewImage 无法匹配 current 导致白屏或跳图
直接用 uni.previewImage 传 current: this.imageList[index] 看似合理,但一旦用户在预览中滑动、再删除某张图,current 对应的路径就可能不在新数组里了——uni.previewImage 找不到该路径,就白屏或自动 fallback 到第一张。
真正要做的不是“删完重设 current”,而是让预览逻辑和数据状态解耦:
- 删除前不主动关闭预览,但必须记录被删项的
path(或更稳妥的id) - 删完后立刻用
this.imageList.findIndex(item => item.path === deletedPath)查新索引 - 若找不到,说明这张图已被删,此时应主动调用
uni.hideToast()+this.previewVisible = false关闭预览框,避免残留状态
sizeType 配置不当引发内存溢出或重复缩略图
安卓低端机上用 sizeType: ['original', 'compressed'],相册会显示两套缩略图,体验割裂;全用 ['original'] 则极易触发 OOM —— 实测 9 张原图在 Android 6.0 设备上平均占 300MB+ 内存。
推荐组合是 sizeType: ['compressed'],配合后续按需压缩(如用 uni.compressImage 对单张做质量/尺寸控制),既规避闪退,又保证上传体积可控:
- 仅在需要高清图的场景(如商品主图)才对特定图片调用
compressImage - 默认预览和上传都走压缩图,减少内存压力
- 注意:iOS 上
compressed效果有限,可加一层 canvas 裁剪兜底
删除后预览数组错乱的本质是 UI 与数据不同步
问题不在 splice 本身,而在组件没响应数据变更。比如你用 v-for="(img, i) in imageList" 渲染,但 imageList 更新后,uni.previewImage 的 urls 数组没同步更新,或 current 还指向旧引用。
关键动作有三步:
- 删除时用
const deletedItem = this.imageList.splice(index, 1)[0]拿到被删对象,保留其path或id - 删完立即刷新预览组件的
urls属性(如果是自定义组件)或重置this.previewUrls = [...this.imageList] - 如果用了自定义预览组件,必须监听
imageList的变化:watch: { imageList: { handler() { this.syncCurrentIndex() }, immediate: true } }
自定义样式组件里 delete 图标遮挡点击区域
很多实现把删除按钮放在 image 标签内部或绝对定位覆盖,结果导致 @click 事件被拦截,点图预览失效。
正确做法是:
- 删除按钮用
view包裹,设position: absolute+z-index: 2,但pointer-events: none让点击穿透到底层image - 只在
hover或长按态下开启pointer-events: auto(uni-app 中可用v-if控制显隐) - 或者更简单:删除按钮放在
image外层view里,用flex布局叠加,避免层级干扰


















