uni.previewimage 是最稳、最省事、全端兼容的图片预览方案,无需自写缩放逻辑;movable-view 不支持缩放,强行用 scale 会导致手势错乱、坐标失准;调用需严格匹配 urls 数组和 current 字符串格式,注意跨平台路径差异与事件拦截。

直接用 uni.previewImage 就能实现,不用自己写缩放逻辑——这是最稳、最省事、全端兼容的方案。
为什么别硬套 movable-view 做缩放
很多人一上来就想用 movable-view + scale 属性控制图片缩放,结果真机上手势错乱、拖拽偏移、iOS 微信白屏。根本原因是:movable-view 本身不支持缩放,它只管平移;强行加 transform: scale() 会破坏内部坐标系,x/y 值不再对应视觉位置,后续 touch 事件全乱套。
- 缩放后必须重置
this.x = 0、this.y = 0,否则拖拽起点错位 - 双指缩放得自己监听
touchstart/touchmove,算event.touches[0]和event.touches[1]的距离比,event.changedTouches在手指抬起后会丢数据 - iOS 微信 WebView 需加
touch-action: none并在touchmove里调preventDefault(),否则第一次缩放后手势失效
uni.previewImage 要传对参数才生效
调用没反应?大概率是 urls 或 current 格式不对。这个 API 看似简单,但路径匹配极其严格。
-
urls必须是数组,哪怕单图也要写成['https://xxx.jpg'],不能传字符串 -
current必须和urls里某一项**完全一致**:协议、域名、大小写、斜杠都不能差,否则安卓定位失败、小程序静默退出 - H5 不支持
file://路径,/static/xxx.jpg可以,但需确保文件真在 static 目录下 - 微信小程序要求网络图必须在 downloadFile 白名单域名内,本地路径(如
../../assets/)真机必失败,且控制台不报错
点击事件要加 .stop 防干扰
image 组件默认不触发原生触摸事件,尤其在 App 和小程序端,@click 可能被父容器拦截或冒泡打断,导致预览不弹出。
- 写成
@click.stop="handlePreview(src)"或@touchstart.stop更可靠 - 如果页面用了
scroll-view或swiper,不加.stop容易触发滚动而非预览 - 多图循环渲染时,确保
src是响应式变量(比如v-for里的item.src),别用计算属性或异步赋值,否则预览时可能显示上一张图
复杂场景下要注意的边界点
真正上线后容易翻车的地方,往往不是缩放逻辑,而是路径、时机和平台差异。
- App 端的临时路径(如
uni.chooseImage返回的file:///)可直接传给uni.previewImage,但微信小程序会报错,跨平台必须做判断 - 网络图要确认服务端开了 CORS(
Access-Control-Allow-Origin: *),否则 App 端加载失败白屏 - 双击放大、滑动切换、下载按钮这些功能
uni.previewImage全自带,别重复造轮子;但如果你需要在预览页加自定义按钮(比如“复制链接”),就得放弃它,改用自研组件——那就绕不开上面那些 touch 同步和坐标映射的坑











