前端国际化 i18n:多语言、日期与数字格式

FreeGuideOnline 最新 2026-06-15

前端国际化 (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 对象,或第三方库如 dayjsluxon

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(美国) vs 1 234,56(法国)
  • 货币符号位置:$1,234.00 vs 1 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 或 HTML dir="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 管理多语言文本
  • 使用 Intl API 处理日期和数字格式
  • 复数、插值、RTL 等核心概念

下一步建议

  • 尝试将现有小项目添加多语言支持
  • 研究你所用框架的 i18n 生态(如 vue-i18n、react-intl)
  • 学习国际化工具的 CLI 工作流(如 formatjs 提取、编译)

国际化并不是一次性的任务,而是需要贯穿整个开发周期。从今天开始,告别硬编码,让你的应用走向世界吧!