1、国际化是什么?
在构建面向全球用户的应用系统时,"国际化(i18n )" 是基础能力之一。系统层面的国际化不仅包含前端国际化 ,也包括后端国际化:
前端国际化
- 多语言文本渲染
- 货币、时间、数字等本地格式展示
- 实时语言切换能力
后端国际化
- 接口多语言返回(如:标题、产品详情等)
- 日志记录语言、服务端渲染内容的语言切换
- 数据库中支持多语言字段
- 后端根据 Accept-Language / Token 判断用户语言
本文聚焦于 前端国际化技术实践,尤其是如何选型、实现与维护 UI 层的多语言能力。
2、为什么需要前端国际化?
- 让用户使用自己熟悉的语言,是用户友好设计的重要一环。
- 不同市场需要以本地化方式推广产品,支持国际化是出海的前提条件。
- 多个国家地区要求系统必须提供本地语言版本的协议或功能。
3、前端国际化方案演进与对比
早期方案:基于 jQuery 插件
- 使用
jquery.i18n.properties
,兼容 Java.properties
格式; - 手动替换 DOM 文本。
优点 :简单、快速接入,适合老系统或小型项目,这个方案很难见到了。
缺点:缺乏插值、懒加载、框架集成能力。
现代框架方案:Vue / React
Vue (vue-i18n
)
- 使用
$t('key')
替代原文; - 支持变量插值、复数形式、懒加载语言包。
React (react-i18next
)
- 使用
useTranslation()
Hook; - 支持异步加载、上下文管理、嵌套 key、复数、格式化。
优点 :与组件深度集成、功能强大。
缺点:接入配置稍复杂,需统一 key 命名规范。
自动化方案:AI 翻译 + 自动提取
典型工具:
vite-plugin-auto-i18n
i18n-extract
、i18next-scanner
自动扫描中文文本,提取成语言 key,并调用 AI(如腾讯翻译、Google Translate)生成目标语言翻译。
优点 :显著提升效率,降低遗漏风险,适合多人协作项目。
缺点:AI 翻译需人工校对,不适用于正式文案场景。
方案对比
特性 | jQuery 插件 | Vue/React 集成 | 自动提取工具链 |
---|---|---|---|
适配框架 | 弱 | 强 | 中(结合构建工具) |
插值支持 | 基础 | 完善 | 支持 |
懒加载支持 | 否 | 是 | 是 |
易用性 | 简单 | 中 | 自动化高,但需配置 |
适合场景 | 传统后台、小项目 | 中大型项目、前后端分离 | 多人协作、自动化构建系统 |
前端国际化核心流程
🧩 Step 1:抽取语言 key
将所有页面文案提取为 key,例如:
js
$t('login.welcome') // ✅
$t('欢迎登录') // ❌
🧩 Step 2:维护语言包
语言包建议结构如下:
bash
/locales/
├─ en-US/
│ ├─ login.json
│ ├─ dashboard.json
└─ zh-CN/
├─ login.json
├─ dashboard.json
🧩 Step 3:检测用户语言
js
const lang = localStorage.getItem('lang') || navigator.language || 'en-US';
🧩 Step 4:加载语言资源
使用 Vue/React 的 i18n 插件异步加载语言 JSON 文件。
🧩 Step 5:支持语言切换
js
i18n.global.locale = 'en'; // Vue 3
i18n.changeLanguage('zh'); // React
4、示例
4.1 Vue + vue-i18n 示例
bash
npm install vue-i18n@next
ts
import { createI18n } from 'vue-i18n';
const i18n = createI18n({
locale: 'zh-CN',
messages: {
'en-US': { welcome: 'Welcome!' },
'zh-CN': { welcome: '欢迎!' }
}
});
vue
<template>
<div>{{ $t('welcome') }}</div>
</template>
4.2 React + react-i18next 示例
bash
npm install react-i18next i18next
ts
import { useTranslation } from 'react-i18next';
function App() {
const { t, i18n } = useTranslation();
return (
<div>
<h1>{t('welcome')}</h1>
<button onClick={() => i18n.changeLanguage('en-US')}>EN</button>
</div>
);
}