在開發一個訂單預算系統時,我們需要在前端動態計算「利潤率差額」,格式為百分比(帶 % 符號)保留4位小數,但實際傳給后端時必須是純數字(浮點數),以便后端正常以 BigDecimal
類型接收并處理。
然而,我們在某次提交數據到后端時,系統直接拋出以下異常:
告訴我們傳遞的是null ,告訴我無法轉換
問題分析
前端相關代碼如下所示:
// 利潤率差額 profitRateDiff(百分比 + % 符號,保留4位小數)
const orderRevenueActual = Number(this.costData.orderRevenueActual) || 0
let profitRateDiff = '0.0000%' // 👈 注意這里是字符串!
if (orderRevenueActual !== 0) {const rate = (netProfitDiff / orderRevenueActual) * 100profitRateDiff = `${rate.toFixed(4)}%`
}
this.$set(this.costData, 'profitRateDiff', profitRateDiff)
這段代碼表面上看沒毛病,邏輯嚴謹,結果也是正確顯示出“28.4212%”這樣格式化的字符串。
然而,致命問題在于:
👉 profitRateDiff
被直接設置為 字符串類型(帶 %)
👉 最終提交接口時 this.costData.profitRateDiff
仍是字符串 "28.4212%"
👉 后端嘗試將 "28.4212%"
轉換為 BigDecimal
,但 %
字符不是合法數字格式
👉 報錯!
正確寫法
1. 存值用數字,不要包含 %
字符,如果需要可以重新寫個方法轉過去
const orderRevenueActual = Number(this.costData.orderRevenueActual) || 0
let profitRateDiff = 0 // 👈 注意初始化為數字
if (orderRevenueActual !== 0) {const rate = (netProfitDiff / orderRevenueActual) * 100profitRateDiff = +rate.toFixed(4) // 強轉為小數數字
}
this.$set(this.costData, 'profitRateDiff', profitRateDiff) // 仍是純數字
比如:
methods: {formatPercent(value) {if (value == null || isNaN(value)) return '0.0000%'return value.toFixed(4) + '%'}
}
最佳實踐總結
需求 | 實現方式 |
---|---|
存儲 | 使用數字 28.4212 |
展示 | 格式化顯示為 28.4212% |
提交后端 | 保證 costData.profitRateDiff 是數字類型 |
寫在最后
這次坑給我們的經驗是:
前端顯示歸顯示,存儲歸存儲,一定要分離
在與后端協作中,要嚴格約定字段類型:數字就是數字、字符串就是字符串
對格式化展示的字段,盡量使用計算屬性、方法或者過濾器處理,而不要將格式化后的值直接賦值到數據模型中