前端国际化 i18n:多语言、日期与数字格式
前端国际化 (i18n) 完全指南:多语言、日期与数字格式
国际化(Internationalization,缩写 i18n)是为软件产品提供不同语言和地区支持的过程。对于前端应用,i18n 不仅仅是翻译文字,还涉及日期、时间、数字、货币等格式的本地化。本教程将从零开始,带你掌握现代前端项目中 i18n 的核心概念与实践,即使你是零基础,也能轻松上手。
1. 为什么需要国际化?
- 全球用户覆盖:让你的应用触达不同语言和文化的用户。
- 专业用户体验:日期、时间、数字按本地习惯显示,避免用户困惑。
- 维护性:将文本与代码分离,方便非开发人员参与翻译和修改。
2. 国际化与本地化的区别
- 国际化 (i18n):在代码层面准备好支持多种语言和区域的基础设施(如文本提取、格式化函数)。
- 本地化 (L10n):实际为某种语言和地区提供翻译文本、日期格式等资源的过程。
本教程主要聚焦于国际化实现。
3. 基础概念:Locale(语言区域)
一个 locale(语言区域)标识符通常由语言代码和国家/地区代码组成,例如:
en-US:美国英语zh-CN:中国大陆简体中文zh-TW:中国台湾繁体中文fr:法语(未指定地区)
前端国际化需要根据当前用户的 locale 动态选择翻译文本和格式化规则。
4. 三步搭建多语言支持
4.1 准备翻译文本——将文字从代码中抽离
不要直接在代码中写死字符串,而是使用键值对来管理文本。常见的做法是使用 JSON 或 JavaScript 对象定义每种语言的翻译字典。
// locales/en.json
{
"greeting": "Hello, {name}!",
"button_submit": "Submit",
"message_count": "You have {count} new messages."
}
// locales/zh-CN.json
{
"greeting": "你好,{name}!",
"button_submit": "提交",
"message_count": "你有 {count} 条新消息。"
}
避免硬编码:任何显示给用户的文字都应该从这些翻译文件中读取。
4.2 选择 i18n 库
手写 i18n 逻辑非常繁琐,推荐使用成熟的类库。以下是三大主流前端生态的常用库:
| 框架/环境 | 推荐库 | 特点 |
|---|---|---|
| Vue | vue-i18n | 与 Vue 深度集成,支持组合式API |
| React | react-intl(或 react-i18next) | FormatJS 系列,组件化使用 |
| 通用/原生 | i18next | 生态丰富,支持所有框架 |
本教程将以 i18next 为例进行通用讲解,其设计思想适用于任何库。
4.3 初始化 i18next
首先安装 i18next 和框架插件(以 React 为例为 react-i18next,Vue 为 vue-i18n,这里展示纯 JavaScript 初始化)。
npm install i18next
// i18n.js
import i18next from 'i18next';
i18next.init({
resources: {
en: {
translation: { /* 英文翻译对象 */ }
},
'zh-CN': {
translation: { /* 中文翻译对象 */ }
}
},
lng: 'en', // 默认语言
fallbackLng: 'en',
interpolation: {
escapeValue: false // React / Vue 已经安全处理了 XSS
}
});
export default i18next;
在组件中使用翻译函数 t():
// 示例:显示 “你好,Alice!”
const message = i18next.t('greeting', { name: 'Alice' });
5. 处理复数与插值
当文本包含变量(如数字、用户名)时,使用插值语法;对于根据数量变化的文案,使用复数规则。
插值:
{
"greeting": "Hello, {{name}}!" // i18next 默认插值语法为 {{...}}
}
使用:t('greeting', { name: 'John' })
复数:不同语言复数规则差异很大。i18next 支持标准复数后缀(_one, _other 等)。
{
"message_count": "{count} new message",
"message_count_plural": "{count} new messages",
"message_count_0": "No new messages"
}
调用 t('message_count', { count: 5 }) 会根据 count 值自动选择合适形式。
6. 日期时间本地化
不同 locale 的日期展示习惯完全不同:
- 美国:
04/15/2025(月/日/年) - 中国:
2025年4月15日 - 德国:
15.04.2025
推荐使用浏览器内置的 Intl.DateTimeFormat 对象,或第三方库如 dayjs、luxon。
6.1 使用 Intl.DateTimeFormat
const date = new Date(2025, 3, 15, 14, 30);
const formatter = new Intl.DateTimeFormat('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long'
});
console.log(formatter.format(date)); // 2025年4月15日星期二
6.2 结合 i18next 处理日期
可以在 t 函数中返回格式化后的日期字符串,但更好的做法是封装一个根据当前语言切换的日期格式化函数:
function formatDate(date, locale = i18next.language) {
return new Intl.DateTimeFormat(locale).format(date);
}
7. 数字与货币格式化
数字格式同样受 locale 影响:
- 千位分隔符:
1,234.56(美国) vs1 234,56(法国) - 货币符号位置:
$1,234.00vs1 234,00 €
使用 Intl.NumberFormat:
const number = 123456.789;
// 普通数字
new Intl.NumberFormat('de-DE').format(number); // "123.456,789"
// 货币
new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(number);
// "¥123,457" (注意日元无小数)
技巧:不要自行拼接货币符号,始终使用 Intl 处理。
8. 从右到左(RTL)语言支持
阿拉伯语、希伯来语等是从右向左阅读的。除了翻译文字,CSS 布局也需要镜像。
- 使用 CSS 属性
direction: rtl或 HTMLdir="rtl"。 - 现代前端库(如 Material-UI, Ant Design)通常提供内置 RTL 支持。
- 避免书写固定方向的样式(如
margin-left),改用逻辑属性margin-inline-start。
9. 本地化资源管理最佳实践
9.1 按页面或模块拆分翻译文件
避免一个巨大的翻译 JSON 文件。可以按功能模块拆分:
locales/
en/
common.json
dashboard.json
zh-CN/
common.json
dashboard.json
9.2 持续本地化流程
- 使用 TMS(翻译管理系统)如 Lokalise、Crowdin 或 POEditor 协作翻译。
- 自动化提取源文本,并生成翻译文件。
- 避免在代码中直接修改翻译文件,而是通过平台同步。
10. 小结与后续学习
国际化是前端工程化的重要一环。通过本文,你已经掌握了:
- 使用 i18next 管理多语言文本
- 使用
IntlAPI 处理日期和数字格式 - 复数、插值、RTL 等核心概念
下一步建议:
- 尝试将现有小项目添加多语言支持
- 研究你所用框架的 i18n 生态(如 vue-i18n、react-intl)
- 学习国际化工具的 CLI 工作流(如
formatjs提取、编译)
国际化并不是一次性的任务,而是需要贯穿整个开发周期。从今天开始,告别硬编码,让你的应用走向世界吧!