這得從axios中得默認值說起:
Axios 的?transformResponse
axios
?在接收到服務器的響應后,會通過一系列的轉換函數(transformResponse
)來處理響應數據,使其適合在應用程序中使用。默認情況下,axios
?的?transformResponse
?包含以下步驟:
- ?解析 JSON 數據:使用?
JSON.parse
?將響應的 JSON 字符串轉換為 JavaScript 對象。 - ?轉換數據:根據響應的?
Content-Type
,可能進行其他轉換(如將 XML 轉換為對象)。 - ?返回數據:最終返回處理后的數據供應用程序使用。
默認的?transformResponse
// node_modules/axios/lib/defaults.js
const defaults = {// 其他默認配置...transformResponse: [function transformResponse(data) {// 對 data 進行任意轉換處理if (typeof data === 'string') {try {data = JSON.parse(data);} catch (e) { /* 忽略解析錯誤 */ }}return data;}],// 其他默認配置...
};
在這個過程中,
JSON.parse
?將 JSON 字符串轉換為 JavaScript 對象。然而,JavaScript 的?Number
?類型在處理某些數字時會自動去除不必要的尾隨零,例如將?12.00
?轉換為?12
。
為什么?JSON.parse
?會舍去小數點后的零?
是因為?JSON.parse
?將數字字符串解析為 JavaScript 的?Number
?類型。在 JavaScript 中,12.00
?和?12
?被認為是相等的數值,因此?JSON.parse
?會自動優化表示方式,去掉不必要的尾隨零。這是 JavaScript 的預期行為,但在某些需要保留特定小數位數的場景下,這可能會導致問題。
解決方案-------------------------------------
1. 后端返回字符串類型的數據
最直接的方法是讓后端在返回JSON數據時,將需要保留小數位數的數字字段作為字符串返回。這樣,前端接收到的數據將保留原始的小數點后零。
后端示例(以Java為例):?
public class ResponseData {@JsonFormat(shape = JsonFormat.Shape.STRING)private String number;// getters and setters
}
返回的JSON:?
{"number": "12.00"
}
前端處理:?
axios.get('/api/your-api').then(response => {const numberString = response.data.number; // "12.00"const number = parseFloat(numberString); // 如果需要數值類型,可以轉換const formattedNumber = number.toFixed(2); // "12.00"
});
2. 自定義transformResponse
如果無法修改后端返回的數據格式,可以在axios
的配置中自定義transformResponse
,在數據被解析為JavaScript對象之前,對特定字段進行處理,確保數字以字符串形式保留小數點后的零。
示例代碼:?
import axios from 'axios';const axiosInstance = axios.create({transformResponse: [function (data) {let parsedData;try {parsedData = JSON.parse(data, (key, value) => {if (typeof value === 'number' && Number.isFinite(value)) {return value.toFixed(2);}return value;});} catch (e) {return data;}return parsedData;}],
});axiosInstance.get('/api/your-api').then(response => {console.log(response.data); // 數字字段將以字符串形式保留兩位小數
});
3. 在前端手動處理數字格式
如果后端返回的數字是數值類型,且你只需要在前端展示時保留小數點后的零,可以在渲染時進行格式化,而不改變原始數據。
示例代碼(Vue.js):
<template><div>格式化后的數字: {{ formattedNumber }}</div>
</template><script>
export default {data() {return {number: 12.00 // 假設這是從后端獲取的數字};},computed: {formattedNumber() {return this.number.toFixed(2); // "12.00"}}
};
</script>
4. 使用字符串處理庫
如果需要更復雜的數字格式化,可以使用第三方庫如numeral.js
或accounting.js
來處理數字格式。
使用numeral.js
的示例:?
npm install numeral
import axios from 'axios';
import numeral from 'numeral';axios.get('/api/your-api').then(response => {const number = response.data.number; // 假設是數值類型 12const formattedNumber = numeral(number).format('0.00'); // "12.00"console.log(formattedNumber);
});
總結-------------------------------------------------------
為了避免前后端交互中數字格式的問題,最佳實踐是:
- ?后端返回字符串類型的數據,明確保留小數點后的零。? ?-----首選
- ?自定義
transformResponse
,在數據解析階段對特定字段進行處理。 - ?前端進行格式化,在展示時根據需要格式化數字。