问题现象

后端接口返回:

{
  "price": 5.0
}

在浏览器 Network → Response 中可以看到:

{
  "price": 5.0
}

但是在 Network → Preview 中:

{
  "price": 5
}

前端页面显示:

5

而不是:

5.000

原因分析

JSON Number 不保存数字格式

JSON 中的数字类型只保存 数值本身,不会保存数字格式。

例如:

{
  "price": 5
}

和:

{
  "price": 5.0
}

对于 JSON 解析器来说完全一样。


JavaScript:

5 === 5.0;

结果:

true

原因是 JavaScript 使用:

Number

类型存储数字。

它不会记录:

  • 小数位数量
  • 尾随 0
  • 原始输入格式

例如:

const price = 5.0;
 
console.log(price);

输出:

5

浏览器为什么 Response 和 Preview 不一致?

Response

Network 中 Response 显示的是:

后端返回的原始 HTTP 响应文本

例如:

{
  "price": 5.0
}

Preview

Preview 显示的是:

浏览器解析 JSON 后生成的 JavaScript 对象

解析过程:

JSON.parse('{"price":5.000}');

结果:

{
  price: 5;
}

因为:

5.000 → Number → 5

如何解决

方案一:后端返回字符串

适用于:

  • 金额
  • 汇率
  • 单价
  • 财务数据
  • 精度敏感字段

后端返回:

{
  "price": "5.000"
}

前端:

row.price;

结果:

"5.000"

优点:

  • 保留展示格式
  • 不丢失精度
  • 适合财务系统

缺点:

前端计算时需要转换:

Number(price);

方案二:前端格式化显示

如果接口返回:

{
  "price": 5
}

展示时处理:

Number(price).toFixed(3);

结果:

5.000

项目中建议统一处理:

export function formatDecimal(value, digit = 3) {
  if (value === null || value === undefined) {
    return '-';
  }
 
  return Number(value).toFixed(digit);
}

使用:

{{ formatDecimal(row.price, 3) }}

效果:

后端返回页面显示
55.000
5.05.000
5.0005.000
5.1235.123

Java 后端处理

BigDecimal 问题

Java:

BigDecimal price =
    new BigDecimal("5.000");

序列化:

{
  "price": 5.0
}

但是:

浏览器解析后:

{
  price: 5;
}

依然会丢失格式。


返回字符串

例如:

price.toPlainString()

返回:

{
  "price": "5.000"
}

或者:

@JsonSerialize(using = ToStringSerializer.class)
private BigDecimal price;

企业系统最佳实践

对于:

  • ERP
  • CRM
  • SRM
  • 财务系统
  • 报价系统
  • 供应链系统

推荐设计:

数据层

使用:

BigDecimal

保证计算精度。


API 层

金额字段:

{
  "amount": "123.4500"
}

使用字符串传输。


前端展示层

统一格式化:

formatDecimal(amount, 4);

项目实践建议

仅用于展示

例如:

  • 单价
  • 汇率
  • 税率
  • 成本

推荐:

后端返回字符串
+
前端统一格式化

参与计算

例如:

  • 总价
  • 毛利
  • 成本计算

推荐:

后端 BigDecimal 计算
+
返回字符串结果

避免 JavaScript Number 精度问题。


总结

核心原因:

JSON Number 只保存数值,不保存数字格式,因此 5.000 在 JavaScript 中会变成 5

如果需要保留:

5.000

必须:

  1. 后端返回字符串:
{
  "price": "5.000"
}

或者:

  1. 前端展示时格式化:
Number(price).toFixed(3);

企业系统中(ERP / SRM / 财务类系统)通常采用:

BigDecimal
+
String API 返回
+
前端统一格式化展示