你希望基于这段 React + Ant Design (antd) 国际化的实战代码,提炼一份符合 CSDN 文档风格、兼具知识点讲解和实战案例的教程,方便学习和复用。
以下是一份完整的 CSDN 风格文档,贴合你提供的代码场景,重点讲解 antd 国际化 + 项目业务国际化(i18n)的实现。
React + Ant Design (antd) 国际化完整实战教程
前言
在中大型前端项目中,国际化(i18n)是不可或缺的需求,尤其是面向多地区用户的系统。React 项目中搭配 Ant Design(以下简称 antd)开发时,国际化需要兼顾两个层面:
antd 组件库自身的国际化(如 DatePicker、Modal、Button 等组件的内置文字、日期格式)
项目业务代码的国际化(如自定义表单标签、按钮文字、提示信息等)
本文基于 React + antd 3.x(注:你提供的代码使用 antd 3.x 语法,如 LocaleProvider、date-picker/locale),结合实战代码,详细讲解完整的国际化实现方案,最终实现多语言切换(中文 / 俄语 / 哈萨克语)的效果。
一、环境准备
- 核心依赖
确保项目中已安装以下核心依赖(对应本文实战场景):
bash
# React 核心
npm install react react-dom --save
# antd 3.x(注意版本,4.x+ 国际化语法有差异)
npm install antd@3.x --save
# 日期处理(antd DatePicker 依赖)
npm install moment --save
# 项目业务国际化(可选,本文对应代码中的 @i18n)
# 常用方案:i18next / react-i18next
npm install i18next react-i18next --save
React 核心
npm install react react-dom --save
antd 3.x(注意版本,4.x+ 国际化语法有差异)
npm install antd@3.x --save
日期处理(antd DatePicker 依赖)
npm install moment --save
项目业务国际化(可选,本文对应代码中的 @i18n)
常用方案:i18next / react-i18next
npm install i18next react-i18next --save
- 依赖说明
antd@3.x:本文实战基于 3.x 版本,4.x+ 已移除 LocaleProvider,改用 ConfigProvider,后续会补充版本差异说明。
moment:antd 3.x 日期组件依赖 moment 处理日期格式,且 moment 自身支持国际化,需引入对应语言包。
@i18n:项目自定义的业务国际化实例(常见封装为 i18next),用于处理业务文字的多语言切换。
二、核心知识点讲解
1.antd 3.x 组件库国际化实现
antd 3.x 提供 LocaleProvider 组件作为国际化入口,用于包裹整个应用(或需要国际化的组件),传入对应语言的 locale 配置,即可实现组件内置文字的国际化。
1.1 引入对应语言的 locale 包
antd 3.x 内置了多种语言的 locale 配置,直接从 antd/lib/locale-provider/ 或对应组件(如 DatePicker)的 locale 目录引入即可,以本文的 3 种语言为例:
javascript
// 1. 全局组件 locale(适用于 Modal、Select、Button 等所有组件)
import KKLocale from 'antd/lib/locale-provider/kk_KZ'; // 哈萨克语(哈萨克斯坦)
import RULocale from 'antd/lib/locale-provider/ru_RU'; // 俄语(俄罗斯)
import ZHCNLocale from 'antd/lib/locale-provider/zh_CN'; // 中文(中国)
// 2. 日期组件单独 locale(DatePicker 专用,优先级高于全局 locale)
import zh_CN_DateLocale from 'antd/lib/date-picker/locale/zh_CN';
import ru_RU_DateLocale from 'antd/lib/date-picker/locale/ru_RU';
import kk_KZ_DateLocale from 'antd/lib/date-picker/locale/kk_KZ';
1.2 配置 LocaleProvider
LocaleProvider 需包裹需要国际化的组件树,通常在根组件或页面级组件中使用,传入对应语言的 locale 属性:
javascript
import { LocaleProvider } from 'antd';
import React from 'react';
// 根据当前语言获取对应的 antd locale 配置
const getAntdLocale = (lang) => {
switch (lang) {
case 'zh-CN':
return ZHCNLocale;
case 'ru-RU':
return RULocale;
case 'kk-KZ':
return KKLocale;
default:
return ZHCNLocale;
}
};
const App = () => {
// 从缓存中获取当前系统语言(对应你提供的代码逻辑)
const lang = sessionStorage.getItem('SYSTEM_LANG') || localStorage.getItem('SYSTEM_LANG') || 'zh-CN';
const antdLocale = getAntdLocale(lang);
return (
// 包裹整个应用,实现 antd 组件国际化
<LocaleProvider locale={antdLocale}>
{/* 你的业务组件 */}
<DeliverModal />
</LocaleProvider>
);
};
export default App;
1.3 DatePicker 单独配置国际化
antd 的 DatePicker 组件除了继承 LocaleProvider 的全局配置,还支持通过 locale 属性单独配置,适用于「全局语言与日期组件语言不一致」的场景,对应你代码中的用法:
javascript
import { DatePicker } from 'antd';
import moment from 'moment';
// 步骤1:根据当前语言获取 DatePicker 专属 locale
const getDatePickerLocale = (lang) => {
switch (lang) {
case 'zh-CN':
return zh_CN_DateLocale;
case 'ru-RU':
return ru_RU_DateLocale;
case 'kk-KZ':
return kk_KZ_DateLocale;
default:
return zh_CN_DateLocale;
}
};
// 步骤2:DatePicker 组件传入 locale 属性
const DeliverForm = () => {
const lang = sessionStorage.getItem('SYSTEM_LANG') || 'zh-CN';
const dateLocale = getDatePickerLocale(lang);
return (
<DatePicker
locale={dateLocale} // 单独配置日期组件国际化
disabledDate={(current) => current && current.valueOf() > Date.now()}
/>
);
};
2.moment 日期国际化配置
antd DatePicker 依赖 moment 处理日期显示格式,因此需要同时配置 moment 的国际化,否则日期的月份、星期等文字无法对应目标语言。
2.1 引入 moment 语言包
javascript
import moment from 'moment';
// 引入对应语言包(按需引入,减少打包体积)
import 'moment/locale/zh-cn'; // 中文
import 'moment/locale/ru'; // 俄语
import 'moment/locale/kk'; // 哈萨克语
2.2 设置 moment 当前语言
根据系统当前语言,切换 moment 的 locale,注意 moment 的语言标识与 antd 可能存在差异(如 中文:zh-cn vs antd 的 zh_CN):
javascript
// 根据系统语言设置 moment 语言
const setMomentLocale = (lang) => {
switch (lang) {
case 'zh-CN':
moment.locale('zh-cn'); // moment 标识:zh-cn
break;
case 'ru-RU':
moment.locale('ru'); // moment 标识:ru
break;
case 'kk-KZ':
moment.locale('kk'); // moment 标识:kk
break;
default:
moment.locale('zh-cn');
}
};
// 调用:获取系统语言并设置
const lang = sessionStorage.getItem('SYSTEM_LANG') || 'zh-CN';
setMomentLocale(lang);
3.项目业务代码国际化实现
业务代码中的自定义文字(如「物流公司」、「取消」、「确定」),需要通过专门的国际化工具(如 i18next)实现,对应你代码中的 i18n.lg() 方法。
3.1 核心思路
定义多语言配置文件(如 zh-CN.json、ru-RU.json、kk-KZ.json),存储键值对形式的文字映射。
初始化国际化实例(封装为 @i18n),加载对应语言的配置文件。
在业务代码中通过 i18n.lg('key') 读取对应语言的文字。
3.2 实战封装(i18next 示例)
步骤 1:创建多语言配置文件
在项目 src/locales 目录下创建以下文件:
javascript
// zh-CN.json(中文配置)
{
"填写物流信息": "填写物流信息",
"取消": "取消",
"确定": "确定",
"物流公司": "物流公司",
"请选择物流公司": "请选择物流公司",
"其他物流公司": "其他物流公司",
"物流单号": "物流单号",
"退货日期": "退货日期",
"请填写退货日期": "请填写退货日期"
}
// ru-RU.json(俄语配置)
{
"填写物流信息": "Заполните информацию о логистике",
"取消": "Отмена",
"确定": "Подтвердить",
"物流公司": "Логистическая компания",
"请选择物流公司": "Пожалуйста, выберите логистическую компанию",
"其他物流公司": "Другая логистическая компания",
"物流单号": "Номер логистического документа",
"退货日期": "Дата возврата товара",
"请填写退货日期": "Пожалуйста, заполните дату возврата товара"
}
步骤 2:初始化 i18next 实例
创建 src/locales/index.js,封装国际化实例:
javascript
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
// 导入多语言配置文件
import zhCN from './zh-CN.json';
import ruRU from './ru-RU.json';
import kkKZ from './kk-KZ.json';
// 配置资源
const resources = {
'zh-CN': {
translation: zhCN
},
'ru-RU': {
translation: ruRU
},
'kk-KZ': {
translation: kkKZ
}
};
// 初始化 i18n
i18n
.use(initReactI18next) // 结合 react-i18next 使用
.init({
resources,
lng: sessionStorage.getItem('SYSTEM_LANG') || localStorage.getItem('SYSTEM_LANG') || 'zh-CN', // 默认语言
fallbackLng: 'zh-CN', // 备用语言
interpolation: {
escapeValue: false // React 已自带 XSS 防护,关闭此选项
}
});
export default i18n;
步骤 3:在项目入口引入
在 src/index.js 中引入,使整个项目生效:
javascript
import React from 'react';
import ReactDOM from 'react-dom';
import './locales'; // 引入国际化配置
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
- 语言切换逻辑实现
国际化的核心是「动态切换语言」,需要实现以下功能:
提供语言切换组件(如 Select 下拉框)
切换语言时,更新 sessionStorage/localStorage 中的语言标识
重新设置 antd locale、moment locale、i18n 实例的语言
刷新组件(或重新渲染)使配置生效
实战代码示例
javascript
import React from 'react';
import { Select } from 'antd';
import moment from 'moment';
import i18n from './locales';
import { ZHCNLocale, RULocale, KKLocale } from './antd-locales'; // 封装的 antd locale
import { cache } from 'config';
const Option = Select.Option;
const LanguageSwitch = () => {
// 切换语言的核心方法
const handleLanguageChange = (lang) => {
// 1. 缓存语言标识(供其他组件读取)
sessionStorage.setItem(cache.SYSTEM_LANG, lang);
localStorage.setItem(cache.SYSTEM_LANG, lang);
// 2. 更新 i18n 实例语言(业务文字)
i18n.changeLanguage(lang);
// 3. 更新 moment 语言(日期格式)
setMomentLocale(lang);
// 4. 更新 antd locale(组件内置文字)
// 注:antd 3.x 的 LocaleProvider 需重新渲染组件才能生效,可通过状态提升实现
window.location.reload(); // 简单有效(生产环境可优化为无刷新重新渲染)
};
// 复用 moment 语言设置方法
const setMomentLocale = (lang) => {
switch (lang) {
case 'zh-CN':
moment.locale('zh-cn');
break;
case 'ru-RU':
moment.locale('ru');
break;
case 'kk-KZ':
moment.locale('kk');
break;
default:
moment.locale('zh-cn');
}
};
// 当前语言
const currentLang = sessionStorage.getItem(cache.SYSTEM_LANG) || 'zh-CN';
return (
<Select
value={currentLang}
onChange={handleLanguageChange}
style={{ width: 200, margin: 20 }}
>
<Option value="zh-CN">中文</Option>
<Option value="ru-RU">Русский</Option>
<Option value="kk-KZ">Қазақша</Option>
</Select>
);
};
export default LanguageSwitch;
三、关键问题与注意事项
- antd 3.x vs 4.x+ 国际化差异
javascript
import { ConfigProvider } from 'antd';
import zhCN from 'antd/es/locale/zh_CN';
import ruRU from 'antd/es/locale/ru_RU';
const App = () => {
const lang = sessionStorage.getItem('SYSTEM_LANG') || 'zh-CN';
const locale = lang === 'zh-CN' ? zhCN : ruRU;
return (
<ConfigProvider locale={locale}>
{/* 业务组件 */}
</ConfigProvider>
);
};
| 版本 | 核心组件 | 引入路径 | 关键差异 |
|---|---|---|---|
| 3.x | LocaleProvider | antd/lib/locale-provider/ | 需单独引入 DatePicker 等组件的 locale |
| 4.x+ | ConfigProvider | antd/es/locale | 统一 locale 配置,无需单独配置 DatePicker |
antd 4.x+ 国际化示例(简化版):
javascript
import { ConfigProvider } from 'antd';
import zhCN from 'antd/es/locale/zh_CN';
import ruRU from 'antd/es/locale/ru_RU';
const App = () => {
const lang = sessionStorage.getItem('SYSTEM_LANG') || 'zh-CN';
const locale = lang === 'zh-CN' ? zhCN : ruRU;
return (
<ConfigProvider locale={locale}>
{/* 业务组件 */}
</ConfigProvider>
);
};
- 语言标识一致性
moment、antd、i18next 的语言标识可能不一致,需做好映射,避免出现「语言切换后日期格式未更新」的问题,核心映射表(本文场景):
| 系统语言标识 | antd locale 标识 | moment locale 标识 |
|---|---|---|
| zh-CN | zh_CN | zh-cn |
| ru-RU | ru_RU | ru |
| kk-KZ | kk_KZ | kk |
- 打包体积优化
按需引入语言包,避免打包所有语言的配置文件:
antd locale:只引入项目需要的语言(如 zh_CN、ru_RU、kk_KZ),不引入其他无用语言。
moment 语言包:按需引入,不引入 moment/min/locales-all.js(全量语言包)。
业务国际化配置:使用 i18next-http-backend 实现语言包懒加载(生产环境推荐)。 - 表单校验提示的国际化
表单校验的 message 需使用国际化方法读取,而非硬编码,对应你代码中的逻辑:
javascript
// 正确(国际化)
rules={[{ required: true, message: i18n.t(`请选择物流公司`) }]}
// 错误(硬编码,无法切换语言)
rules={[{ required: true, message: "请选择物流公司" }]}
四、完整效果演示(对应你的代码)
初始语言为中文:Modal 标题为「填写物流信息」,DatePicker 显示「年 / 月 / 日」,下拉框显示「其他物流公司」。
切换为俄语:Modal 标题变为「Заполните информацию о логистике」,DatePicker 显示俄语日期格式,下拉框显示「Другая логистическая компания」。
填写表单并提交:校验提示为对应语言,提交后数据格式正常(日期格式已通过 moment 格式化)。
总结
React + antd 国际化需兼顾组件库国际化和业务代码国际化两个层面,前者依赖 antd 的 LocaleProvider/ConfigProvider,后者依赖 i18next 等工具。
antd 3.x 中 DatePicker 需单独配置 locale,且依赖 moment 实现日期文字国际化,需做好两者的语言标识映射。
语言切换的核心是「更新缓存 + 刷新配置 + 重新渲染」,简单场景可使用页面刷新,复杂场景可实现无刷新重新渲染。
实战中需注意打包体积优化和表单校验、提示信息的全量国际化,避免遗漏硬编码文字。