uni-app 不支持用 filter 实现图片压缩或路径转换,因其仅支持同步格式化且无法调用异步 api;正确做法是在 methods、setup 或自定义 hook 中分平台处理压缩与路径转换逻辑。

uni-app 没有「过滤器(filter)」机制能直接实现图片压缩或路径转换——Vue 2 的全局/局部 filter 在 uni-app 的 Vue 3 编译模式下已被移除,且即使在 Vue 2 模式中,filter 也仅用于模板中字符串/数值的**格式化显示**,无法执行异步操作(如读取文件、canvas 绘制、调用 uni.compressImage 或 pathToBase64),更不能改变图片实际上传行为。
所以,别在 filters 选项里写压缩逻辑,那根本跑不起来。
为什么 filter 不能用来做图片压缩或路径转换
filter 是纯同步函数,只接收输入值并返回新值;而图片压缩涉及:
– 异步 API 调用(uni.chooseImage、uni.getImageInfo、uni.canvasToTempFilePath)
– 文件系统读写(plus.io、uni.getFileSystemManager().readFile)
– canvas 渲染上下文创建与绘制
这些全被 filter 的设计模型排除在外。
真正该用的地方:setup / methods / 自定义 Hook
所有压缩和路径转换逻辑必须放在可执行异步代码的位置:
– methods 中响应用户操作(如点击“上传”)
– setup 里配合 ref/async 函数封装流程
– 抽成独立函数或 Composition API Hook(如 useImageCompress()),便于多端复用
- 不要写:
filters: { compressPath: (path) => uni.compressImage({ src: path }) }→ 语法错误 + 无法 await - 应该写:
const handleUpload = async (tempPath) => { const compressed = await compressImageOnPlatform(tempPath); upload(compressed); }
跨端路径转换必须手动分平台处理
所谓“路径转 base64”,不同端底层机制完全不同,不存在一个通用 filter 字符串替换能搞定:
– H5:需 fetch + arraybuffer + btoa,或 FileReader
– App(iOS/Android):用 plus.io 或插件 pathToBase64
– 微信小程序:用 wx.getFileSystemManager().readFile({ encoding: 'base64' })
每种都要单独判断 uni.getSystemInfoSync().platform,再走对应分支
- 错例:
{{ tempFilePath | toBase64 }}→ 模板里无法判断平台,也无法 await - 对的做法:在方法内先
if (platform === 'mp-weixin') { ... },再调用对应 API
容易忽略的关键点:tempFilePath 不是万能路径
uni.chooseImage 返回的 tempFilePaths 是临时路径,生命周期极短(尤其在 H5 和小程序中),未及时处理就会失效。很多开发者试图把它丢进 filter 再“慢慢转”,结果上传时路径已 404。
正确节奏是:选图 → 立即压缩或转 base64 → 得到稳定输出(tempFilePath 或 base64 字符串)→ 再传给上传逻辑。
- H5 下
tempFilePath实际是 blob URL,pathToBase64会失败,必须走fetch+arraybuffer - App 端若用
uni.compressImage,注意quality是最大边长,不是质量值,传30可能反而变大 - 所有转换后务必校验结果:base64 是否以
data:image/xxx;base64,开头?tempFilePath是否真实存在(可用uni.getFileInfo验证)?











