如何使用Intl.NumberFormat格式化货币每单位的单价?
货币/单位组合单价的格式化实现方法
Intl.NumberFormat 原生确实不支持同时启用currency和unit两种格式化样式,要实现2 336 €/m²、$2.336/ac这类符合本地书写习惯的单价格式,直接用分拆处理的思路就可以,不需要引入额外第三方库。
通用实现方案(兼容性最好)
核心逻辑是把单价拆成「带货币格式的数值」和「计价单位」两部分,分别处理后拼接,完全适配不同地区的格式习惯:
- 第一步:用
style: 'currency'配置初始化格式化实例,传入对应地区的locale、货币类型,直接输出符合本地习惯的「货币+数值」组合,比如法语(法国)环境下2336欧元会输出2 336,00 €,英语(美国)环境下2.336美元会输出$2.34 - 第二步:直接在格式化好的货币数值字符串后拼接
/加对应单位即可,不需要调整原有字符串的顺序——Intl.NumberFormat已经帮你处理好了货币符号在数字前/后的位置、千分位分隔符、小数位规则,直接拼接不会出格式错误 - 可直接复用的代码示例:
/** * 格式化单价(货币/单位) * @param {number} value - 数值 * @param {string} currency - ISO 4217货币代码,比如'EUR'/'USD'/'CNY' * @param {string} unit - 计价单位文本,比如'm²'/'ac' * @param {string} [locale=navigator.language] - 地区代码,默认取浏览器当前语言 * @returns {string} 格式化后的单价文本 */ function formatUnitPrice(value, currency, unit, locale = navigator.language) { const currencyFormatter = new Intl.NumberFormat(locale, { style: 'currency', currency, maximumFractionDigits: 2 // 可按业务需求调整小数位数 }) return `${currencyFormatter.format(value)}/${unit}` } // 测试用例 console.log(formatUnitPrice(2336, 'EUR', 'm²', 'fr-FR')) // 输出 2 336,00 €/m² console.log(formatUnitPrice(2.336, 'USD', 'ac', 'en-US')) // 输出 $2.34/ac console.log(formatUnitPrice(12345, 'CNY', '㎡', 'zh-CN')) // 输出 ¥12,345.00/㎡
复杂场景适配方案
如果需要更精细地控制各部分内容(比如要单独给货币、数值、单位加不同样式),可以用formatToPartsAPI拿到格式化后的分段内容,再插入单位部分拼接,避免硬编码位置:
function formatUnitPricePrecise(value, currency, unit, locale = navigator.language) { const formatter = new Intl.NumberFormat(locale, { style: 'currency', currency, maximumFractionDigits: 2 }) const parts = formatter.formatToParts(value) // 追加单位分段 parts.push( { type: 'literal', value: '/' }, { type: 'unit', value: unit } ) return parts.map(part => part.value).join('') }
避坑提示
- 不要手动硬编码货币符号位置、千分符、小数点规则,不同地区的书写习惯差异极大,全部交给
Intl处理即可 - 如果需要单位也做多语言适配,可以提前维护一份不同locale对应的单位文本映射表,拼接时取对应语言的单位就行,比如英语环境下平方米用
sq m,中文环境用㎡ - 上线前针对目标覆盖的地区做简单的用例测试,确认分隔符、位置符合当地习惯即可,核心逻辑不需要调整
内容的提问来源于stack exchange,提问作者Crow
相关产品推荐
相关产品推荐

