过滤器对超大数字完全无效,因其介入时JSON已解析失真;须在uni.request中设dataType: 'String'并用json-bigint解析,后续全程保持字符串类型。

过滤器根本不能解决超大数字精度丢失——它连执行机会都没有。 尤其在小程序端,filters 选项被编译器直接忽略;即使 H5 端能跑,也只作用于字符串渲染,对 id、amount 这类参与计算或传参的数值毫无保护能力。真正要防的是 JSON 解析阶段的截断,不是模板层的显示。
为什么过滤器对超大数字完全无效
超大数字(如 18 位订单 ID)在 uni.request 响应后,会先被 JSON.parse() 解析。JavaScript 的 Number 类型安全整数上限是 2^53 - 1(约 9007199254740991),超出部分直接失真,比如 9223372036854775808 变成 9223372036854776000。这个过程发生在过滤器介入之前,且不可逆。
- 过滤器只接收已解析完成的 JS 值(此时精度早已丢失),无法回溯原始字符串
- 小程序平台(微信/支付宝/字节)编译时直接剥离
filters配置,{{ id | keepString }}不报错也不执行 - 即便你在
Vue.filter里写return String(value),传进来的已经是错误的数字,转字符串只是把错值固化
必须在响应解析前拦截原始字符串
核心思路:阻止 JSON.parse() 对大数做默认转换,保留原始响应体字符串,再用 json-bigint 等工具安全解析。
- 设置
dataType: 'String'—— 让uni.request不自动解析,返回原始字符串 - 手动用
jsonBig.parse()处理,它会把大数字转为BigInt或保持字符串(取决于配置) - 若解析失败(比如非 JSON 响应),降级使用原生
JSON.parse() - 注意:uView 等封装库可能覆盖
dataType,需检查其源码(如luch-request/adapters/index.js)并注释掉强制parse的逻辑
const jsonBig = require('json-bigint')<br>uni.request({<br> url: '/api/order',<br> dataType: 'String', // 关键<br> success: (res) => {<br> try {<br> const data = jsonBig({ storeAsString: true }).parse(res.data)<br> // 此时 data.orderId 是字符串,不会失真<br> this.order = data<br> } catch (e) {<br> this.order = JSON.parse(res.data)<br> }<br> }<br>)后续使用时务必用字符串操作,别转 Number
一旦你拿到的是正确字符串形式的大 ID(如 "9223372036854775808"),所有后续环节都必须保持字符串类型:
- 传给
uni.navigateTo的url参数中直接拼接:order?id=${this.order.id} - 作为请求参数发给后端时,确保是字符串:
uni.request({ data: { id: this.order.id } }) - 不要调用
Number(this.order.id)或+this.order.id,哪怕只是想判断真假——if (this.order.id)足够 - 如果 UI 上需要显示,直接
{{ order.id }}即可,无需过滤器“格式化”
最容易被忽略的点:很多人修复了解析阶段,却在某个 computed 里写了 Number(this.order.id).toFixed(0),又把字符串重新转回错的数字——这种二次转换比不修还危险。


















