Element UI(Vue 2.x)国际化完全指南:多语言配置、vue-i18n 兼容与源码级原理解析
【免费下载链接】elementA Vue.js 2.0 UI Toolkit for Web项目地址: https://gitcode.com/gh_mirrors/eleme/element
Element 组件库默认内置简体中文,但在国际化产品中,你需要将其切换为英文、日文、法文等数十种语言,并与vue-i18n深度整合以支持运行时语言切换。本文以官方 i18n 文档为主线,完整覆盖 Element 多语言配置的三种引入方式、vue-i18n@5.x与@6.x的兼容方案、CDN 加载语言包等全部实战步骤,并结合本仓库 locale 模块源码 剖析use/t/i18n三个核心 API 的底层实现,帮助你彻底理解 Element 的国际化机制,并能够自行定制、扩展语言包。
一、Element 国际化机制总览
Element 的组件文案(如分页器、日期选择器、消息弹框的按钮文字)统一通过一套语言包(locale)管理。语言包的默认文件为 src/locale/lang/zh-CN.js,其结构是el命名空间下按组件分组的键值对象,例如:
export default { el: { pagination: { goto: '前往', pagesize: '条/页', total: '共 {total} 条', pageClassifier: '页' }, // colorpicker / datepicker / select / cascader / ... 每个组件一组 } }组件内部并不直接书写文案,而是通过 src/mixins/locale.js 混入的t方法读取当前语言包:
import { t } from 'element-ui/src/locale'; export default { methods: { t(...args) { return t.apply(this, args); } } };最终所有文案的查询、解析与切换都汇聚到 src/locale/index.js 这一核心模块。它对外暴露三个 API:
| API | 作用 | 对应源码 |
|---|---|---|
use(lang) | 切换当前语言包 | src/locale/index.js#L40-L42 |
t(path, options) | 按点路径取文案,支持{name}占位符插值 | src/locale/index.js#L23-L38 |
i18n(fn) | 注入自定义翻译处理器(对接 vue-i18n 等) | src/locale/index.js#L44-L46 |
其中t的查找逻辑是:先用自定义的i18nHandler尝试翻译,若返回空则回退到内置语言包按路径逐级取值,最后调用 src/locale/format.js 中的模板函数完成{total}、{checked}等占位符替换。format内部使用正则/(%|)\{([0-9a-zA-Z_]+)\}/g匹配占位符,并从参数对象中取值替换(参见 src/locale/format.js#L3-L43)。
二、基本用法:为 Element 设置语言
Element 组件内部默认使用中文,若希望使用其他语言,则需要进行多语言设置。以英文为例,在main.js中:
2.1 完整引入 Element
// 完整引入 Element import Vue from 'vue' import ElementUI from 'element-ui' import locale from 'element-ui/lib/locale/lang/en' Vue.use(ElementUI, { locale })Vue.use(ElementUI, opts)时,opts.locale会被传入插件的install函数,进而调用locale.use(opts.locale)完成语言包切换,该调用链在 src/index.js#L183-L185 中有明确体现:
const install = function(Vue, opts = {}) { locale.use(opts.locale); locale.i18n(opts.i18n); // ... 注册所有组件 };2.2 按需引入 Element
// 按需引入 Element import Vue from 'vue' import { Button, Select } from 'element-ui' import lang from 'element-ui/lib/locale/lang/en' import locale from 'element-ui/lib/locale' // 设置语言 locale.use(lang) // 引入组件 Vue.component(Button.name, Button) Vue.component(Select.name, Select)注意这里的element-ui/lib/locale即构建产物中的 locale 模块,其默认导出对象包含use、t、i18n三个方法(对应 src/locale/index.js#L48 的export default { use, t, i18n }),所以可以在按需注册组件前手动调用locale.use(lang)完成切换。
三、用 webpack 替换默认语言包(NormalModuleReplacementPlugin)
如果使用其它语言,默认情况下中文语言包依旧是被引入的。这是因为 locale 模块在源码层面直接import defaultLang from 'element-ui/src/locale/lang/zh-CN'(见 src/locale/index.js#L1),构建产物同样保留了这一默认依赖。你可以使用 webpack 的NormalModuleReplacementPlugin把默认语言包直接替换为目标语言,从而避免多打包一份中文包:
webpack.config.js
{ plugins: [ new webpack.NormalModuleReplacementPlugin(/element-ui[\/\\]lib[\/\\]locale[\/\\]lang[\/\\]zh-CN/, 'element-ui/lib/locale/lang/en') ] }该正则同时匹配/与\两种路径分隔符,兼容 Windows 与 Linux/macOS 下的打包环境。替换后,整个构建产物将不再携带中文语言包,包体积更小。
四、兼容vue-i18n@5.x
Element 兼容vue-i18n@5.x,搭配使用能更方便地实现多语言切换——切换应用语言时,Element 组件文案会跟随vue-i18n同步变化:
import Vue from 'vue' import VueI18n from 'vue-i18n' import Element from 'element-ui' import enLocale from 'element-ui/lib/locale/lang/en' import zhLocale from 'element-ui/lib/locale/lang/zh-CN' Vue.use(VueI18n) Vue.use(Element) Vue.config.lang = 'zh-cn' Vue.locale('zh-cn', zhLocale) Vue.locale('en', enLocale)这种兼容能力来自 src/locale/index.js#L9-L21 的i18nHandler默认实现:它会探测原型上的$t方法以及Vue.locale,若检测到 5.x 的vue-i18n环境,则首次使用时通过deepmerge把 Element 语言包与 vue-i18n 的 messages 深度合并(Vue.locale(Vue.config.lang, deepmerge(lang, Vue.locale(Vue.config.lang) || {}, { clone: true }))),随后委托$t进行翻译,从而让两套文案共用同一个翻译管线。
五、兼容其他 i18n 插件
如果不使用vue-i18n@5.x,而是用其他的 i18n 插件,Element 将无法自动兼容,但是可以自定义 Element 的 i18n 处理方法——通过i18n选项注入你自己的翻译函数:
import Vue from 'vue' import Element from 'element-ui' import enLocale from 'element-ui/lib/locale/lang/en' import zhLocale from 'element-ui/lib/locale/lang/zh-CN' Vue.use(Element, { i18n: function (path, options) { // path 形如 'el.datepicker.today',options 为插值参数对象 // 在这里调用你自定义 i18n 插件的翻译方法并返回结果 } })传入的i18n函数会通过locale.i18n(opts.i18n)(src/index.js#L185)覆盖默认的i18nHandler(对应 src/locale/index.js#L44-L46),此后每次组件调用t都会优先进入你的翻译函数。若你的函数返回null或undefined,t会回退到内置语言包继续查找(src/locale/index.js#L23-L26),这一设计保证了自定义翻译与内置语言的平滑共存。
六、兼容vue-i18n@6.x
默认不支持 6.x 的vue-i18n(6.x 移除了Vue.locale全局 API,改为实例化VueI18n),你需要手动处理——把 Element 语言包展开合并进VueI18n的messages,再把实例的t方法注入给 Element:
import Vue from 'vue' import Element from 'element-ui' import VueI18n from 'vue-i18n' import enLocale from 'element-ui/lib/locale/lang/en' import zhLocale from 'element-ui/lib/locale/lang/zh-CN' Vue.use(VueI18n) const messages = { en: { message: 'hello', ...enLocale // 或者用 Object.assign({ message: 'hello' }, enLocale) }, zh: { message: '你好', ...zhLocale // 或者用 Object.assign({ message: '你好' }, zhLocale) } } // Create VueI18n instance with options const i18n = new VueI18n({ locale: 'en', // set locale messages, // set locale messages }) Vue.use(Element, { i18n: (key, value) => i18n.t(key, value) }) new Vue({ i18n }).$mount('#app')要点说明:
...enLocale与Object.assign两种写法等价,Element 语言包本身就是{ el: { ... } }结构的普通对象,可以直接展开进 messages;- 通过
i18n: (key, value) => i18n.t(key, value)把VueI18n实例的t包装后注入 Element,组件文案便与VueI18n实例的locale状态完全联动; new Vue({ i18n })将实例挂载到根组件,运行时切换i18n.locale即可全局切换语言。
七、按需加载里定制 i18n
按需引入组件时同样可以接入vue-i18n@6.x,区别在于不能通过Vue.use(Element, ...)传参,而要直接调用 locale 模块的i18n方法:
import Vue from 'vue' import DatePicker from 'element/lib/date-picker' import VueI18n from 'vue-i18n' import enLocale from 'element-ui/lib/locale/lang/en' import zhLocale from 'element-ui/lib/locale/lang/zh-CN' import ElementLocale from 'element-ui/lib/locale' Vue.use(VueI18n) Vue.use(DatePicker) const messages = { en: { message: 'hello', ...enLocale }, zh: { message: '你好', ...zhLocale } } // Create VueI18n instance with options const i18n = new VueI18n({ locale: 'en', // set locale messages, // set locale messages }) ElementLocale.i18n((key, value) => i18n.t(key, value))这里的ElementLocale.i18n(...)与完整引入时Vue.use(Element, { i18n })内部执行的locale.i18n(opts.i18n)(src/index.js#L185)是同一个入口,因此按需引入时只要手动调用一次即可让已注册组件的t走自定义翻译。
八、通过 CDN 的方式加载语言文件
在非模块化(直接<script>标签)场景下,Element 提供 UMD 格式的语言包文件,通过全局变量ELEMENT操作:
<script src="//unpkg.com/vue@2"></script> <script src="//unpkg.com/element-ui"></script> <script src="//unpkg.com/element-ui/lib/umd/locale/en.js"></script> <script> ELEMENT.locale(ELEMENT.lang.en) </script>搭配vue-i18n使用(此时用的是vue-i18n的全局版本与Vue.localeAPI,即 5.x 风格的全局注册方式):
<script src="//unpkg.com/vue@2"></script> <script src="//unpkg.com/vue-i18n/dist/vue-i18n.js"></script> <script src="//unpkg.com/element-ui"></script> <script src="//unpkg.com/element-ui/lib/umd/locale/zh-CN.js"></script> <script src="//unpkg.com/element-ui/lib/umd/locale/en.js"></script> <script> Vue.locale('en', ELEMENT.lang.en) Vue.locale('zh-cn', ELEMENT.lang.zhCN) </script>注意 UMD 语言包挂载到全局后,ELEMENT.lang.zhCN对应中文语言包、ELEMENT.lang.en对应英文语言包,而ELEMENT.locale(...)等价于源码中的locale.use(...)方法(src/index.js#L216 将locale.use作为Element.locale暴露)。
九、Element 内置语言一览
目前 Element 内置了以下语言(对应本仓库 src/locale/lang 目录下的语言包文件,该目录实际已包含超过 60 个语言的配置文件,除下表外还有阿塞拜疆语 az、孟加拉语 bn、冰岛语 is、老挝语 lo-LA、马来语 ms、僧伽罗语 si、塞尔维亚拉丁文 sr-Latn、斯瓦希里语 sw、乌兹别克语 uz-UZ、亚美尼亚语 hy-AM 等):
| 语言 | locale 标识 | 语言 | locale 标识 |
|---|---|---|---|
| 简体中文 | zh-CN | 英语 | en |
| 德语 | de | 葡萄牙语 | pt |
| 西班牙语 | es | 丹麦语 | da |
| 法语 | fr | 挪威语 | nb-NO |
| 繁体中文 | zh-TW | 意大利语 | it |
| 韩语 | ko | 日语 | ja |
| 荷兰语 | nl | 越南语 | vi |
| 俄语 | ru-RU | 土耳其语 | tr-TR |
| 巴西葡萄牙语 | pt-br | 波斯语 | fa |
| 泰语 | th | 印尼语 | id |
| 保加利亚语 | bg | 波兰语 | pl |
| 芬兰语 | fi | 瑞典语 | sv-SE |
| 希腊语 | el | 斯洛伐克语 | sk |
| 加泰罗尼亚语 | ca | 捷克语 | cs-CZ |
| 乌克兰语 | ua | 土库曼语 | tk |
| 泰米尔语 | ta | 拉脱维亚语 | lv |
| 南非荷兰语 | af-ZA | 爱沙尼亚语 | ee |
| 斯洛文尼亚语 | sl | 阿拉伯语 | ar |
| 希伯来语 | he | 立陶宛语 | lt |
| 蒙古语 | mn | 哈萨克斯坦语 | kz |
| 匈牙利语 | hu | 罗马尼亚语 | ro |
| 库尔德语 | ku | 维吾尔语 | ug-CN |
| 高棉语 | km | 塞尔维亚语 | sr |
| 巴斯克语 | eu | 吉尔吉斯语 | kg |
| 亚美尼亚语 | hy | 克罗地亚 | hr |
| 世界语 | eo |
十、扩展与贡献新的语言包
如果你需要使用列表之外的语言,可以为本仓库贡献语言文件:只需在 src/locale/lang 目录下新增一个语言配置文件即可。新语言包需遵循统一的结构约定——顶层导出{ el: { 组件名: { 文案键: 值 } } },可参照 src/locale/lang/en.js 或 src/locale/lang/zh-CN.js 的完整结构(覆盖 colorpicker、datepicker、select、cascader、pagination、messagebox、upload、table、tree、transfer、image、pageHeader、popconfirm、empty 等全部组件的文案,含{total}、{checked}等占位符,需一并保留)。
需要特别说明的是,use切换语言包时并不做深校验,语言包结构越接近默认语言包,组件文案的命中率越高;未命中的键会回退为空字符串(见 src/locale/index.js#L34-L37 的if (!value) return ''分支),因此在新增语言包时建议以 zh-CN 或 en 为模板逐组补齐,避免界面出现空白文案。
十一、总结:Element 国际化的三条路线怎么选
- 仅切换静态语言:用
Vue.use(ElementUI, { locale })或按需场景下的locale.use(lang),最简单直接; - 需要运行时动态切换语言:接入
vue-i18n(5.x 自动兼容,6.x 按第六、七节手动接线),让 Element 与业务文案共享同一翻译管线; - 深度定制翻译逻辑:通过
Vue.use(Element, { i18n: fn })或locale.i18n(fn)注入自定义处理器,Element 会在自定义翻译返回空时自动回退内置语言包; - 追求极致包体积:用 webpack
NormalModuleReplacementPlugin在构建期替换掉默认中文语言包。
理解 src/locale/index.js 中use/t/i18n三者的协作关系——先自定义翻译、再内置语言包回退、最后占位符插值——你就能在任何构建方式(完整引入、按需引入、CDN)下从容完成 Element 的多语言适配。
【免费下载链接】elementA Vue.js 2.0 UI Toolkit for Web项目地址: https://gitcode.com/gh_mirrors/eleme/element
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考