解决 Vue 中大整数精度丢失问题 —— 以 `degId` 为例
解决 Vue 中大整数精度丢失问题 —— 以 degId 为例
在使用 Vue 进行前端开发时,我们常常会遇到从后端获取的大整数 ID(如 degId),这些 ID 在 JavaScript 中处理时可能会出现精度丢失的问题。本文将以一个实际案例说明这个问题,并提供解决方案。
🧨 问题描述
在项目文件 monthSatisfied.vue 的如下代码中:
1 | let records = res.data.records; |
res.data.records 返回的数据中包含非常大的数字类型的 degId,例如:
1 | { |
但打印出的 voteColumns 却显示为:
1 | [1935593557239328800, ...] |
这表明 JavaScript 对大整数进行了自动精度转换,导致数据不准确。
❓ 原因分析
JavaScript 使用 IEEE-754 双精度浮点数格式来存储数值,其安全整数范围是:
1 | Number.MIN_SAFE_INTEGER = -9007199254740991 |
而上面的 degId 超出了这个范围,因此会被自动“四舍五入”或“截断”,造成数据错误。
✅ 解决方案
方法一:前端手动将 degId 转换为字符串
这是最简单且实用的做法,适用于你无法修改后端接口的情况。
修改代码如下:
1 | this.voteColumns = records.map(record => String(record.degId)); |
同时,在其他使用 record.degId 的地方也应统一转为字符串:
1 | rowData[`dept_${String(record.degId)}`] = record.scores[index]?.score || '-'; |
这样可以确保键名一致,避免因为类型不同而导致数据查找失败。
方法二:后端返回字符串形式的 degId
如果你有权限修改后端接口,建议直接返回字符串类型的 degId:
1 | { |
这样前端无需额外处理,从根本上解决了精度丢失问题。
🧪 示例对比
| 原始值 | JS Number 类型输出 | 字符串处理后 |
|---|---|---|
| 1935593557239328769 | 1935593557239328800 | "1935593557239328769" |
可以看到,使用字符串是最稳妥的方式。
📌 总结
| 问题原因 | 解决方法 |
|---|---|
degId 是超大整数,超出 JS 数值精度范围 |
后端返回字符串类型或前端手动转换为字符串 |
前端解析 degId 时精度丢失 |
所有涉及 degId 的地方统一用字符串处理 |
💡 推荐做法(最佳实践)
✅ 如果你能控制后端接口,优先让后端返回字符串类型的 ID:
1 | "degId": "1935593557239328769" |
🚫 不推荐继续使用 Number 处理超大整数,容易引发不可预知的 bug。
🧩 拓展阅读
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 From Zero to Hero!