首页
/ Ant Design ConfigProvider 国际化(locale)实战:运行时切换语言与本地化支持组件全景

Ant Design ConfigProvider 国际化(locale)实战:运行时切换语言与本地化支持组件全景

2026-09-06 19:15:53作者:宣海椒Queenly

导读

在 Ant Design 中,大部分组件内置的文案默认是英文(如 Pagination 的上一页/下一页、DatePicker 的占位符、Table 的"暂无数据"等)。要在一套应用中为这些组件提供本地化支持,官方推荐的唯一入口就是 ConfigProviderlocale 属性。本文基于仓库中 locale 演示代码 及其配套说明(locale.md),讲解"哪些组件需要国际化支持、如何在演示与真实项目中切换语言、locale 数据从注入到消费的底层链路",并结合 locale 模块 源码与 国际化官方指南,给出可直接复制运行的完整方案。读完本文,你将掌握 ConfigProvider locale 的正确用法、dayjs 语言包同步的必要性,以及 70+ 语言包的结构与扩展方式。


一、locale 演示要解决的核心问题

配置演示(locale.md)的定位非常明确:

此处列出 Ant Design 中需要国际化支持的组件,你可以在演示里切换语言。

它说明两件事:其一,Ant Design 内存在一批内置文案需要跟随语言包变化的组件;其二,这些组件被集中放进一个演示页,用来直观展示 ConfigProviderlocale 在运行时切换语言的完整效果。

与它配套的 locale.tsx 演示页集中渲染了如下组件:PaginationSelectDatePickerTimePickerRangePickerModal(含 Modal.info/Modal.confirm 静态方法)、PopconfirmTransferCalendarFormInputInputNumberTableUploadTourQRCodeImageDividerButton。它们几乎全部出现在 Locale 接口 所声明的语言包条目中(PaginationDatePickerTimePickerCalendarTableModalTourPopconfirmTransferSelectUploadFormQRCodeglobal 等),也就是说演示页与语言包数据结构一一对应——这正是"需要国际化支持的组件"清单的直接来源。


二、演示页解剖:如何在同一页面内切换语言

整个演示由两个 React 组件构成:内部 Page(负责渲染需要本地化的业务 UI)和外部 App(负责持有并切换语言状态、包裹 ConfigProvider)。

2.1 语言状态与切换逻辑

const App: React.FC = () => {
  const [locale, setLocale] = useState<Locale>(enUS);

  const changeLocale = (e: RadioChangeEvent) => {
    const localeValue = e.target.value;
    setLocale(localeValue);
    if (!localeValue) {
      dayjs.locale('en');
    } else {
      dayjs.locale('zh-cn');
    }
  };

  return (
    <>
      <div style={{ marginBottom: 16 }}>
        <Radio.Group value={locale} onChange={changeLocale}>
          <Radio.Button key="en" value={enUS}>English</Radio.Button>
          <Radio.Button key="cn" value={zhCN}>中文</Radio.Button>
        </Radio.Group>
      </div>
      <ConfigProvider locale={locale}>
        <Page />
      </ConfigProvider>
    </>
  );
};

关键点有三:

  1. 语言包即组件文案快照enUSzhCNantd/locale/en_USantd/locale/zh_CN 两个完整语言包对象,直接作为 Radio 的 value,选中哪个 Radio,就把哪个对象赋给 locale state。类型约束 ConfigProviderProps['locale'] 可复用官方导出的 Locale 类型。
  2. ConfigProvider 只需包裹一次:改变 locale state 会触发 ConfigProvider 重新渲染,进而让整个子树共享新的语言上下文,演示页里的 PaginationCalendarModal 等文案会即时刷新。
  3. 必须同步 dayjs 的语言:antd 内置的 date 类组件(DatePicker、TimePicker、Calendar、RangePicker)基于 dayjs 实现。antd 语言包只负责 antd 自身的文案,dayjs 的周起点、月份、季度等日期语义需要单独配置。演示中:
import 'dayjs/locale/zh-cn';
dayjs.locale('en');

切到英文时 dayjs.locale('en'),切到中文时 dayjs.locale('zh-cn')。这正是官方 国际化指南 反复强调的 "for date-picker i18n, import dayjs/locale/xxx"。

2.2 Page 覆盖的"本地化组件全家桶"

Page 内部按块渲染了大量组件,便于肉眼验证切换效果,例如:

  • Pagination defaultCurrent={1} total={50} showSizeChanger:验证每页条数选择器的文案(zh_CN 为"条/页");
  • SelectDatePickerTimePickerRangePicker:验证占位符与面板操作按钮;
  • Modal(受控弹窗)、Modal.infoModal.confirm:验证确认框的"确定/取消"按钮文案;
  • PopconfirmTransfer(含 showSearch)、Calendar fullscreen={false}:验证气泡确认与穿梭框搜索等文案;
  • Form(含必填校验规则)与 InputNumber:验证校验报错文案来自 Form.defaultValidateMessages
  • Table(含 filters)、Upload(picture-card 三种状态)、Tour(三步引导)、QRCode status="expired":验证空数据、上传状态、刷新等语义化文案。

一句话总结该演示的结构:外层一个 ConfigProvider 提供 locale,内部一屏组件负责"验收",这是生产项目"语言切换 + 全局文案一致性"的最小可运行模板。


三、语言包从注入到消费的底层链路

了解演示写法之后,值得深入到 locale 模块ConfigProvider 实现 中,看一份语言对象到底是如何"流"到每个组件里的。

3.1 Locale 数据结构的顶层形状

components/locale/index.tsx#L21-L69 定义了 Locale 接口:除 locale 标识字段外,每个可本地化组件对应一个 xxxLocale 字段。以 zh_CN 语言包 为例,其文件开头即组合了来自子模块的语言片段:

import Pagination from '@rc-component/pagination/locale/zh_CN';
import Calendar from '../calendar/locale/zh_CN';
import DatePicker from '../date-picker/locale/zh_CN';
import TimePicker from '../time-picker/locale/zh_CN';

随后是 globalplaceholder/close/sortable/show/hide)、TablefilterTitle/emptyText/selectAll 等)、Form(含 defaultValidateMessages 与校验模板 '${label}不是一个有效的${type}')、ModalPopconfirmTransferQRCode 等完整条目。由此可见每个语言包都是按组件维度组织的"文案树",这也解释了为什么 en_US.ts 被当作新增语言包的基底模板。

3.2 ConfigProvider 内部:剥离 default 并交给 LocaleProvider

ConfigProvider 的实现 中,locale 处理有两步值得注意:

  1. 兼容 ES Module 场景的 default 解包(index.tsx#L465-L475):当传入的对象带有 default.locale 属性时(例如 import zhCN from 'antd/locale/zh_CN' 被某些打包器二次封装),会自动取出 .default,避免语言不生效;
  2. 将最终 locale 交给内部 LocaleProvider(即旧版本独立存在的 LocaleProvider 组件),并传入 _ANT_MARK__ 内部标记(index.tsx#L680-L682)。

LocaleProvider 本身(locale/index.tsx#L78-L104)做了三件事:

  • 通过 LocaleContext.Provider{ ...locale, exist: true } 写入 React Context(context 定义见 locale/context.ts),子树组件从 useLocale/useContext 读取;
  • 在非生产环境校验 _ANT_MARK__,若没有标记则提示 "LocaleProvider is deprecated. Please use locale with ConfigProvider"——在组件树里直接使用 LocaleProvider 已被废弃,应以 ConfigProvider locale={...} 为准;
  • 调用 changeConfirmLocale(locale?.Modal) 并把清除函数作为副作用,保证 Modal.confirm/Modal.info 等静态方法能读到正确的 Modal 文案。

3.3 语言默认值与消费侧

ConfigProvider 默认引入 defaultLocaleen_US),因此在没有任何配置时,antd 组件文案显示为英文——这正是 国际化指南 开头所说"antd 目前的默认文案是英文"的代码级出处。具体组件消费端则通过 locale/useLocale.ts 之类的工具把"ConfigProvider 上下文语言"与"组件级 locale 覆盖"合并后渲染。整体数据流可概括为:

antd/locale/zh_CN ──> ConfigProvider locale ──> LocaleProvider
   └─> LocaleContext.Provider ──> 各组件 useLocale/useContext ──> 渲染本地化文案
   └─> changeConfirmLocale ──> Modal/Message/Notification 静态方法

四、把演示方案落地到真实项目

演示的核心思路可以直接移植到任何 React 应用。一个更接近真实场景的最小骨架如下(对应 docs/react/i18n.zh-CN.md 的推荐写法):

import zhCN from 'antd/locale/zh_CN';
import enUS from 'antd/locale/en_US';

// dayjs 需要单独处理,否则日期组件的月份等文案不会跟着切换
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';

const App = () => (
  <ConfigProvider locale={zhCN}>
    <YourApp />
  </ConfigProvider>
);

在需要"用户可切换语言"的产品中,参考 locale 演示的做法即可:

  1. 用一个全局状态(如 Context/状态库)保存当前语言标识;
  2. 通过 map 得到对应语言包对象与 dayjs locale 名,语言包切换时同步调用 dayjs.locale(...)
  3. 外层只保留一个 ConfigProvider(可嵌套合并其他配置如 themedirection),让整棵组件树共享同一 locale;
  4. 若用到 Modal.confirm/message 等静态方法,推荐使用 App 组件包裹(app 目录)以消费全局配置;仅在 v5 使用 ConfigProvider.config() 会影响静态方法(见 ConfigProvider 文档)。

另外注意:locale 针对的是组件内置文案。若你的业务文案需要国际化,需要结合 react-intl / i18next 等方案另行处理,ConfigProvider 只负责 antd 组件层,二者互不冲突。


五、可用的语言包范围与扩展方法

Ant Design 在 components/locale/ 下为每种语言提供独立文件,文件名即 语言_地区 形式(如 zh_CN.tsen_US.tsja_JP.ts),按 国际化指南 的清单目前覆盖 70+ 种语言,典型包括:

  • 中文系:zh_CNzh_HKzh_TW
  • 日韩系:ja_JPko_KR
  • 欧美系:en_USen_GBfr_FRde_DEes_ESpt_BR 等;
  • 中东/南亚系:ar_EGfa_IRhe_ILhi_INth_TH 等。

导入方式统一为 import zhCN from 'antd/locale/zh_CN',需配合组件库构建工具支持子路径导出。若缺少目标语言,官方推荐以 en_US.ts 为模板新建语言包并向仓库提交 PR;仓库内 locale 测试 同时覆盖了"切换各语言后组件文案渲染正确"的回归验证,新增语言时需要同步补充对应 dayjs locale 的 import 与测试快照。


六、验证手段:测试与文档交叉佐证

本仓库为 locale 行为提供了多层验证:

想快速验证本文所有结论,可直接把 locale.tsx 演示 拷贝进项目,在 ConfigProvider 外层套一个 App 组件即可获得完整可用、可切换中英文的组件文案预览页。


总结

围绕 locale 演示 的这条线索可以看到:antd 的国际化并非魔法,而是一套"语言包(components/locale)→ ConfigProvider 注入 → LocaleContext 分发 → 各组件消费 + Modal 静态方法同步"的清晰机制。掌握这套机制后,你既能像演示页那样在运行时一键切换语言,也能在接入 dayjs、扩展语言包、排查"切换后日期组件没变"等常见问题时快速定位根因。核心口诀只有一句:语言包交给 ConfigProvider,日期语义交给 dayjs,两者同步切换,组件文案自然跟着变。

登录后查看全文
热门项目推荐
相关项目推荐