不能用 filters 做文件大小单位转换,因 vue 3 已移除 vue.filter,小程序端不执行,h5 端仅残留兼容;应封装 formatbytes 函数,在 setup/data/计算属性中调用,注意类型校验、边界处理、小数精度及跨端兼容性。

为什么不能用 filters 做文件大小单位转换
直接在模板里写 {{ fileSize | formatBytes }} 看起来很干净,但实际在微信/支付宝/字节小程序里根本不会执行——Vue.filter 在 Vue 3 模式(uni-app 默认)下已被移除,H5 端可能残留兼容,其他端编译时直接忽略。你改了 filters/index.js,模板里也写了管道符,结果输出还是原始数字,不是 bug,是机制失效。
推荐做法:封装成可复用的 formatBytes 函数
把逻辑收束到函数里,在 setup、data 或计算属性中调用,跨端稳定,调试也方便。关键点不在“怎么写正则”,而在单位换算的边界处理:
- 输入必须是 number 类型,字符串如
"1024"会导致NaN或静默失败 - 小于 1024 字节统一用
B,不要显示0.98 KB这种反直觉结果 - 小数位数控制:KB/MB 级别保留 1 位小数即可,GB 以上可保留 2 位,避免
1.0000000000000002 GB - 注意负数,虽然文件大小不会是负的,但传入非法值时应返回
"0 B"而非崩溃
示例实现:
const formatBytes = (bytes) => {
if (typeof bytes !== 'number' || bytes = 1024 && l <h3>在 setup 中怎么用才不踩坑</h3><p>别在 <code>setup()</code> 顶层直接调用,否则无法响应式更新;也不要在模板里反复调用函数(会触发多次执行)。正确姿势是:</p>
- 作为计算属性:
const displaySize = computed(() => formatBytes(file.value.size)) - 或在
onMounted/watch里调用并赋值给 ref 变量 - 如果多个地方要用,导出为工具函数放在
utils/format.js,然后import { formatBytes } from '@/utils/format'
特别注意:不要在 v-for 列表里对每个 item 都 inline 调用 formatBytes(item.size),这会显著拖慢长列表渲染速度——先批量格式化好再传入列表数据。
移动端真机上容易被忽略的精度问题
安卓部分低版本 WebView 和微信基础库(2.15.0 以下)对 Number.toFixed() 的处理不一致,(1024.5).toFixed(1) 有时返回 "1024.4"。所以不用 toFixed,改用 Math.round(num * 10) / 10 更稳妥。另外,iOS Safari 对 1024 * 1024 * 1024 这种大数运算有浮点误差,建议用整数除法链式计算,而非一次性除以 1024 ** 3。











