价格格式化
显示本地化的货币和数字格式
问题
显示价格时既涉及数字也涉及货币。例如,美国的价格是 $1,200.50,而在德国,相同数值的欧元价格可能是 1 200,50 €。货币符号的位置、小数点分隔符和千位分隔符都会变化,为每种语言手动编写这些规则几乎无法管理。
解决方案
使用 FormattedNumber 组件(来自 react-intl),并配合 style: 'currency' 选项。该组件会从其 provider 读取当前 locale,并将数字格式化为价格,自动处理该 locale 和指定货币的符号位置、小数点分隔符和分组方式。
步骤
1. 创建价格的客户端组件
来自 react-intl 的格式化组件必须在客户端组件中使用。
新建一个组件 app/components/ProductPrice.tsx。
// app/components/ProductPrice.tsx
'use client';
import { FormattedNumber } from 'react-intl';
type Props = {
price: number;
currencyCode: string; // e.g., "USD", "EUR", "JPY"
};
export default function ProductPrice({ price, currencyCode }: Props) {
return (
<FormattedNumber
value={price}
style="currency"
currency={currencyCode}
/>
);
}
2. 传递格式化选项
FormattedNumber 组件通过以下 props 控制:
value:价格的数值。style: 'currency':指示组件将数字格式化为货币,而不是普通小数。currency:三位字母的 ISO 货币代码(如 'USD'、'EUR')。当使用style: 'currency'时必填。
3. 在页面中使用该组件
现在可以在服务端或客户端组件中使用该组件来显示价格。
// app/[lang]/page.tsx
import ProductPrice from '@/app/components/ProductPrice';
export default function Home() {
const product = {
price: 1299.99,
currency: 'USD',
};
const productInEuros = {
price: 1199.5,
currency: 'EUR',
};
return (
<div>
<h1>Product</h1>
<p>
Price (USD): <ProductPrice price={product.price} currencyCode={product.currency} />
</p>
<p>
Price (EUR): <ProductPrice price={productInEuros.price} currencyCode={productInEuros.currency} />
</p>
</div>
);
}
访问 /en 的用户会看到“价格 (USD):$1,299.99”和“价格 (EUR):€1,199.50”。访问 /es 的用户会看到“价格 (USD):1299,99 US$”和“价格 (EUR):1199,50 €”。