Material UI 本地化完全指南:createTheme Locale 配置、57 种语言支持、自定义翻译与 RTL
【免费下载链接】material-uiMaterial UI: Comprehensive React component library that implements Google's Material Design. Free forever.项目地址: https://gitcode.com/GitHub_Trending/ma/material-ui
本篇技术指南基于 Material UI(MUI)官方文档 Localization 展开,系统讲解如何为基于@mui/material的 React 应用配置非默认语言:从使用createTheme全局注入 locale 文本、理解 locale 对象内部结构与defaultProps生效链路,到创建自定义翻译、处理阿拉伯语等 RTL 语言。读完本文,你可以独立完成多语言应用搭建、为组件文本做定制覆盖,并理解本地化文本在源码层面的具体落地方式。
什么是 Material UI 的本地化
本地化(Localization,又称 "l10n")指将产品或内容适配到特定区域(locale)或市场的过程。Material UI 的默认语言环境是英语(美国,en-US)。当你的应用面向其他语言用户时,只需在主题中声明对应的 locale 对象,组件内置的用户可见文本(分页、评分、自动完成、面包屑、警告提示等)即会切换为对应语言的文案。
需要特别说明:Data Grid 与 Data Grid Pro属于 MUI X 产品线,它们拥有独立的本地化体系,不适用本文介绍的@mui/material/locale配置方式,需要按 MUI X 文档单独配置。
通过 createTheme 全局配置 locale 文本
官方推荐的方式是把 locale 对象作为createTheme的第二个参数传入,从而把本地化文本配置应用到整个主题树中:
import { createTheme, ThemeProvider } from '@mui/material/styles'; import { zhCN } from '@mui/material/locale'; const theme = createTheme( { palette: { primary: { main: '#1976d2' }, }, }, zhCN, ); <ThemeProvider theme={theme}> <App /> </ThemeProvider>;其中zhCN是简体中文 locale,从@mui/material/locale命名空间导入。导入后,ThemeProvider包裹的整棵组件树内所有受本地化影响的组件文本都会使用中文。
源码机制:第二个参数是如何进入主题的
locale 对象并非特殊 API,而是走主题的通用"深层合并"通道。从 createTheme 的签名createTheme(options, ...args)可以看出,所有额外的实参都会传给createThemeNoVars,在那里执行:
// packages/mui-material/src/styles/createThemeNoVars.js(L117-L118) muiTheme = deepmerge(muiTheme, other); muiTheme = args.reduce((acc, argument) => deepmerge(acc, argument), muiTheme);也就是说,zhCN会被整体deepmerge进主题对象。观察 zhCN.ts 可以发现,locale 对象的顶层结构只有一个components键,其下按组件名挂defaultProps。例如:
// packages/mui-material/src/locale/zhCN.ts(节选) export const zhCN: Localization = { components: { MuiTablePagination: { defaultProps: { getItemAriaLabel: (type) => { if (type === 'first') return '第一页'; if (type === 'last') return '最后一页'; if (type === 'next') return '下一页'; return '上一页'; }, labelRowsPerPage: '每页行数:', labelDisplayedRows: ({ from, to, count }) => `第 ${formatNumber(from)} 条到第 ${formatNumber(to)} 条,${count !== -1 ? `共 ${formatNumber(count)} 条` : `至少 ${formatNumber(to)} 条`}`, }, }, // MuiRating、MuiAutocomplete、MuiAlert、MuiPagination、MuiBreadcrumbs ... }, };这些defaultProps之所以能生效,是因为组件渲染时通过useThemeProps/getThemeProps从主题中读取theme.components[组件名].defaultProps并与用户传入的 props 做解析。核心实现在 getThemeProps.ts:
const { theme, name, props } = params; if (!theme || !theme.components || !theme.components[name] || !theme.components[name].defaultProps) { return props; } return resolveProps(theme.components[name].defaultProps, props);resolveProps遵循"显式 props 优先于 defaultProps"的解析规则。因此本地化只提供组件的默认文案,业务侧任何显式传入的 prop(例如给TablePagination传自定义labelDisplayedRows)都会覆盖 locale 提供的文本——这为"整体换语言 + 个别组件定制"的组合使用留出了空间。
locale 对象的结构:Localization 接口
所有 locale 文件都实现同一个类型契约,定义在 LocaleTextApi.ts:
export interface Localization { components?: { MuiAlert?: { defaultProps: Pick<ComponentsPropsList['MuiAlert'], 'closeText'> }; MuiBreadcrumbs?: { defaultProps: Pick<ComponentsPropsList['MuiBreadcrumbs'], 'expandText'> }; MuiTablePagination?:{ defaultProps: Pick<..., 'labelRowsPerPage' | 'labelDisplayedRows' | 'getItemAriaLabel'> }; MuiRating?: { defaultProps: Pick<..., 'emptyLabelText' | 'getLabelText'> }; MuiAutocomplete?: { defaultProps: Pick<..., 'clearText' | 'closeText' | 'loadingText' | 'noOptionsText' | 'openText'> }; MuiPagination?: { defaultProps: Pick<..., 'aria-label' | 'getItemAriaLabel'> }; }; }这份类型说明了本地化影响的组件与可翻译的文本位点:Alert的关闭文本、Breadcrumbs的展开文本、TablePagination的每页行数/显示行数标签与按钮 aria-label、Rating的评分标签与空值标签、Autocomplete的清空/关闭/加载/无选项/打开提示文本,以及Pagination的导航 aria-label 与单项 aria-label。值得注意的是源码注释:核心包不依赖@mui/lab,因此MuiPagination的 props 是内联复制定义的而非引用ComponentsPropsList,这解释了为什么Pagination的defaultProps只含aria-label与getItemAriaLabel两项。
locale 中的数字格式化还依赖 buildFormatNumber:它以Intl.NumberFormat按目标区域(如zh-CN)生成格式化器,对非有限值或运行环境不支持Intl时优雅降级为String(value),保证 SSR 与老旧环境的健壮性。
动态切换语言的官方示例
文档中的交互示例 Locales.js 演示了运行时按用户选择切换语言:用Autocomplete列出Object.keys(locales)作为可选项,选中后用createTheme(theme, locales[locale])重建主题并包一层新的ThemeProvider:
import * as locales from '@mui/material/locale'; const themeWithLocale = React.useMemo( () => createTheme(theme, locales[locale]), [locale, theme], ); return ( <ThemeProvider theme={themeWithLocale}> <Autocomplete options={Object.keys(locales)} ... /> <TablePagination count={2000} rowsPerPage={10} page={1} component="div" onPageChange={() => {}} /> </ThemeProvider> );示例特意选用TablePagination和Autocomplete,因为二者恰好覆盖了 locale 中最直观的可见文本(分页标签、加载/无选项提示)。
支持的语言环境清单
@mui/material/locale的导出清单以 index.ts 为准,它逐一export *了各语言文件并额外导出utils/LocaleTextApi的类型。官方文档列出的受支持 locale 及对应的 BCP 47 语言标签、导入名如下:
| Locale | BCP 47 language tag | Import name |
|---|---|---|
| Amharic | am-ET | amET |
| Arabic (Egypt) | ar-EG | arEG |
| Arabic (Saudi Arabia) | ar-SA | arSA |
| Arabic (Sudan) | ar-SD | arSD |
| Armenian | hy-AM | hyAM |
| Azerbaijani | az-AZ | azAZ |
| Bangla | bn-BD | bnBD |
| Bulgarian | bg-BG | bgBG |
| Catalan | ca-ES | caES |
| Chinese (Hong Kong) | zh-HK | zhHK |
| Chinese (Simplified) | zh-CN | zhCN |
| Chinese (Taiwan) | zh-TW | zhTW |
| Croatian | hr-HR | hrHR |
| Czech | cs-CZ | csCZ |
| Danish | da-DK | daDK |
| Dutch | nl-NL | nlNL |
| English (United States) | en-US | enUS |
| Estonian | et-EE | etEE |
| Finnish | fi-FI | fiFI |
| French | fr-FR | frFR |
| German | de-DE | deDE |
| Greek | el-GR | elGR |
| Hebrew | he-IL | heIL |
| Hindi | hi-IN | hiIN |
| Hungarian | hu-HU | huHU |
| Icelandic | is-IS | isIS |
| Indonesian | id-ID | idID |
| Italian | it-IT | itIT |
| Japanese | ja-JP | jaJP |
| Khmer | kh-KH | khKH |
| Kazakh | kk-KZ | kkKZ |
| Korean | ko-KR | koKR |
| Kurdish (Central) | ku-CKB | kuCKB |
| Macedonian | mk-MK | mkMK |
| Myanmar | my-MY | myMY |
| Malay | ms-MS | msMS |
| Nepali | ne-NP | neNP |
| Norwegian (bokmål) | nb-NO | nbNO |
| Norwegian (nynorsk) | nn-NO | nnNO |
| Pashto (Afghanistan) | ps-AF | psAF |
| Persian | fa-IR | faIR |
| Polish | pl-PL | plPL |
| Portuguese | pt-PT | ptPT |
| Portuguese (Brazil) | pt-BR | ptBR |
| Romanian | ro-RO | roRO |
| Russian | ru-RU | ruRU |
| Serbian | sr-RS | srRS |
| Sinhalese | si-LK | siLK |
| Slovak | sk-SK | skSK |
| Spanish | es-ES | esES |
| Swedish | sv-SE | svSE |
| Thai | th-TH | thTH |
| Turkish | tr-TR | trTR |
| Tagalog | tl-TL | tlTL |
| Ukrainian | uk-UA | ukUA |
| Urdu (Pakistan) | ur-PK | urPK |
| Vietnamese | vi-VN | viVN |
从源码结构看,locale 目录 实际导出的语言文件共 59 个,比上表多出beBY(白俄罗斯语,be-BY)与kuLatn(库尔德语拉丁拼写,ku-Latn)。若目标用户群需要这些变体,可直接从@mui/material/locale导入,即使文档表格尚未列出。
创建自定义翻译与回贡流程
如果需要支持的语言不在上表中,或者想微调现有文案(例如把英文文本改写成品牌化措辞),官方给出的做法是:
- 找到 locale 源码目录 中与你目标语言最接近的文件(如自定义德语变体可基于
deDE.ts); - 将该文件复制到你的项目内,按需修改
defaultProps中的文本; - 从项目内的副本导入并传给
createTheme,例如import { myCustomLocale } from './locales/myLocale';。
由于 locale 对象只是普通的components.{name}.defaultProps结构(见 LocaleTextApi.ts 的Localization接口),你甚至可以只覆盖部分组件的文本,其余字段留空即可——深合并会保留deepmerge后来自其他来源的内容。
文档同时邀请开发者通过 pull request 回贡新翻译,但给出了明确的取舍标准:Material UI 的目标是覆盖使用人数最多的 100 种语言环境,因此使用频率不高的语言(文档举例:仅约 250 万母语者的gl-ES加利西亚语)可能不会被合入。
RTL(从右到左)语言支持
阿拉伯语(arEG、arSA、arSD)、波斯语(faIR)、希伯来语(heIL)、库尔德语(kuCKB)等从右到左书写的语言是受支持的。但仅声明 RTL locale 文本并不改变布局方向——布局层面的镜像、字体间距、图标翻转等需要在文档层面另行处理,官方指引见 RTL 定制指南,其要点是通过dir="rtl"与对应的样式适配使界面从右向左排布。实践时通常二者组合:主题中传入 RTL 语言 locale + 按 RTL 指南调整应用容器方向。
小结:配置链路与适用范围
把整条链路串起来即:createTheme(options, locale)将 locale 深合并进主题 → 各组件通过getThemeProps读取theme.components[名称].defaultProps获得本地化默认文本 → 业务显式 props 始终可覆盖 locale 文案。该机制仅覆盖@mui/material核心组件;MUI X 的 Data Grid、Pickers 等产品线各有独立的本地化配置入口,不可混用。所有语言文件的完整源码均可在 packages/mui-material/src/locale/ 下按语言文件逐一查阅。
【免费下载链接】material-uiMaterial UI: Comprehensive React component library that implements Google's Material Design. Free forever.项目地址: https://gitcode.com/GitHub_Trending/ma/material-ui
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考