Vue Vben Admin Internationalization Guide: i18n Architecture, Language Packs, and Runtime Switching
2026/9/10 7:44:57 网站建设 项目流程

Vue Vben Admin Internationalization Guide: i18n Architecture, Language Packs, and Runtime Switching

【免费下载链接】vue-vben-adminA modern vue admin panel built with Vue3, Shadcn UI, Vite, TypeScript, and Monorepo. It's fast!项目地址: https://gitcode.com/GitHub_Trending/vu/vue-vben-admin

本指南深入解析 Vue Vben Admin(一个基于 Vue 3、Vite、TypeScript 与 Monorepo 架构构建的现代管理后台模板)中内置的国际化(i18n)体系。文章以官方文档docs/src/en/guide/in-depth/locale.md为主线,结合packages/localesplayground应用的真实源码实现,系统讲解默认语言配置、运行时动态切换、翻译文本的添加与使用、全新语言包的扩展流程、远程语言包加载、第三方组件库语言包接入以及移除国际化的完整路径。读完本文,你将掌握在 Vue Vben Admin 任意应用(apps/web-antdplayground等)中落地多语言能力的全部实战方案,并理解其底层语言包加载机制。

国际化架构概览

Vue Vben Admin 基于 Vue i18n(vue-i18n v9 的 Composition API 模式)构建国际化能力,并在 Monorepo 内拆分为两个职责清晰的部分:

  • 通用语言包:位于 packages/locales/src/langs,存放框架级通用文案(如菜单、偏好设置面板、通用按钮等),当前仓库内置了zh-CNen-US语言包;playground应用还演示了zh-TW繁体中文语言包。
  • 应用级语言包:位于各应用(如playground)的src/locales/langs/下,存放业务专属文案,可覆盖或补充通用语言配置。

核心包 packages/locales/src/index.ts 对外导出$t$tei18nloadLocaleMessagesloadLocalesMaploadLocalesMapFromDirsetupI18n以及SupportedLanguagesType等类型,业务代码只需从@vben/locales导入即可。

IDE 插件:i18n Ally

如果你使用 VS Code 作为开发工具,官方推荐安装 i18n Ally 插件。它可以帮助你更便捷地管理国际化文案——安装后,代码中会实时显示对应的语言内容(如上图所示),切换语言时翻译文本也会同步高亮变化,还能在编辑 JSON 语言包时提供缺失 key 的补全与跳转提示。

核心加载机制:@vben/locales 如何工作

在动手配置之前,先理解@vben/locales的底层实现,这有助于你明白"为什么这样配置"。核心实现在 packages/locales/src/i18n.ts:

const i18n = createI18n({ globalInjection: true, legacy: false, locale: '', messages: {}, });
  • legacy: false表示使用 Composition API 模式,配合globalInjection: true可在模板中直接使用$t
  • 语言包通过 Vite 的import.meta.glob批量扫描./langs/**/*.json,由loadLocalesMapFromDir按目录结构(正则/\.\/langs\/([^/]+)\/(.*)\.json$/,前者匹配语言如zh-CN,后者匹配文件名如common)构建localesMap,实现按需懒加载——只有切换到某语言时才动态 import 对应的 JSON,避免首屏打包全部文案。

关键的加载函数loadLocaleMessages(lang)完整流程为:

  1. 若当前语言与目标语言一致,仅更新语言标识后直接返回;
  2. 调用useSimpleLocale同步简单语言偏好;
  3. localesMap异步加载该语言的通用语言包并setLocaleMessage
  4. 调用应用级loadMessages(lang)获取应用语言包,并通过mergeLocaleMessage合并,实现"应用覆盖通用"的效果;
  5. 最后通过setI18nLanguage设置i18n.global.locale.value,并同步更新document.querySelector('html')lang属性,保证页面语义化与无障碍正确。

语言包文件内部结构参见 packages/locales/src/langs/zh-CN(包含authentication.jsoncommon.jsonpreferences.jsonprofile.jsonui.json等按模块拆分的文件),playground应用的同构目录见 playground/src/locales/langs。

配置默认语言

Vue Vben Admin 的默认语言由偏好设置(preferences)驱动,框架默认值为zh-CN(见 packages/@core/preferences/src/config.ts)。要修改默认语言,只需在对应应用内找到src/preferences.ts,覆盖locale的值即可(以下以playground的 playground/src/preferences.ts 为参考模板):

export const overridesPreferences = defineOverridesPreferences({ app: { locale: 'en-US', }, });

偏好设置采用"覆盖默认配置"的设计——defineOverridesPreferences会与框架默认配置深度合并,未覆盖的项自动沿用默认值,因此这里只需写app.locale一行。应用启动时,setupI18n会读取preferences.app.locale作为defaultLocale(参见 playground/src/locales/index.ts 中的setupI18n),完成首屏语言的加载。

动态切换语言

运行时切换语言由两部分组成:

  • 更新偏好设置:通过updatePreferences写入新的app.locale
  • 加载对应的语言包:调用loadLocaleMessages异步加载并激活新语言。
import type { SupportedLanguagesType } from '@vben/locales'; import { loadLocaleMessages } from '@vben/locales'; import { updatePreferences } from '@vben/preferences'; async function updateLocale(value: string) { // 1. Update preferences const locale = value as SupportedLanguagesType; updatePreferences({ app: { locale, }, }); // 2. Load the corresponding language pack await loadLocaleMessages(locale); } updateLocale('en-US');

SupportedLanguagesType是一个由@vben-core/typings中的SupportedLanguages注册表派生出的联合类型(见 packages/locales/src/typing.ts),默认包含'zh-CN''en-US'。得益于类型约束,拼写错误会在编译期被捕获;后续通过模块增强添加新语言后,该联合类型会自动扩展。界面上的语言切换组件正是调用类似的逻辑,用户在偏好设置面板切换语言时,全局文案与第三方组件(dayjs、组件库)会同步更新。

新增翻译文本

::: warning 注意

  • 请不要将业务翻译文本放入@vben/locales包内,这样可以更好地分离业务文案与通用文案的管理边界;
  • 存在多个语言包时,新增翻译文本需要在所有语言包内同步新增对应的 key,避免切换语言后出现缺失。 :::

新增翻译文本只需在对应应用内找到src/locales/langs/目录,新增或修改对应语言的 JSON 文件即可。例如在playground应用中:

src/locales/langs/zh-CN/*.json

{ "about": { "desc": "Vben Admin 是一个现代的管理模版。" } }

src/locales/langs/en-US/*.json

{ "about": { "desc": "Vben Admin is a modern management template." } }

语言包按目录与文件拆分(如common.jsonui.json),loadLocalesMapFromDir会将同一语言目录下的所有 JSON 合并为一个消息对象,因此你可以按模块拆分子文件,key 以点号路径访问(如about.desc)。结合 i18n Ally 插件,新增 key 时它会提示你补齐其他语言的翻译。

使用翻译文本

通过@vben/locales提供的$t,你可以轻松地在代码中使用翻译文本。

在代码中使用

$ti18n.global.t的别名(见 packages/locales/src/index.ts),既可在<script setup>中使用,也可直接在模板中调用:

<script setup lang="ts"> import { computed } from 'vue'; import { $t } from '@vben/locales'; const items = computed(() => [{ title: $t('demos.title') }]); </script> <template> <div>{{ $t('demos.title') }}</div> <template v-for="item in items"> <div>{{ item.title }}</div> </template> </template>

此外,包还导出了$te(判断 key 是否存在)以及useI18n(Composition API 组合式用法,可在组件内获取tlocale等响应式能力),满足更细粒度的场景。得益于globalInjection: true,模板内未显式导入时也可使用全局$t

新增一个语言包

如需新增语言包,按照以下步骤进行(以新增zh-TW繁体中文为例):

  1. packages/locales/src/langs目录下新增对应的语言包文件夹和文件,例如zh-TW/*.json,并翻译对应的文本(当前仓库已包含 packages/locales/src/langs/zh-TW,可作为参照)。

  2. 在对应应用内,找到src/locales/langs目录,新增同构的语言包文件夹和文件zh-TW/*.json

  3. 在应用内新建一个 d.ts 文件(例如src/locales/languages.d.ts),通过模块增强扩展语言类型:

    export type { SupportedLanguages } from '@vben-core/typings'; declare module '@vben-core/typings' { interface SupportedLanguages { 'zh-TW': '繁體中文'; } }

    ::: tip 提示 顶部的 re-export 不可省略——它使该文件成为一个模块,declare module才会被 TypeScript 解释为模块增强(module augmentation);否则文件会被视为环境模块声明(ambient module declaration),从而遮蔽原模块导致其下所有类型丢失。同时应用必须声明@vben-core/typings依赖(Monorepo 内部包通常已具备)。playground的完整示例见 playground/src/locales/languages.d.ts,文件顶部的注释详细说明了这一机制。 :::

  4. 在应用启动时(例如src/bootstrap.ts)注册运行时语言列表,语言切换组件会自动显示新语言:

    import { setSupportLanguages, SUPPORT_LANGUAGES } from '@vben/constants'; setSupportLanguages([ ...SUPPORT_LANGUAGES, { label: '繁體中文', value: 'zh-TW' }, ]);

    playground应用已在 playground/src/bootstrap.ts 中演示了这一步。SUPPORT_LANGUAGES默认包含简体中文与英文(见 packages/constants/src/core.ts),setSupportLanguages会克隆快照并通知所有订阅者(语言切换组件通过onSupportLanguagesChange订阅),因此注册后界面语言下拉框会立即出现"繁體中文"选项。

  5. 如果应用使用了 dayjs、组件库等第三方库,需要在src/locales/index.ts的语言加载逻辑中补充对应的语言包分支(见下文"第三方语言包")。

完成以上步骤后,项目内即可使用新语言包:SupportedLanguagesType联合类型会自动包含'zh-TW'loadLocaleMessagesupdatePreferences等所有相关 API 均获得完整的类型约束;若 value 拼写错误,会在编译期直接报错。

界面切换语言功能

如果你想关闭界面上的语言切换显示按钮,只需在对应应用的src/preferences.ts中覆盖widget.languageToggle

export const overridesPreferences = defineOverridesPreferences({ widget: { languageToggle: false, }, });

框架默认languageToggle: true,且支持languageToggleButtonPosition: 'header' | 'none' | 'user-dropdown'三种位置配置(见 packages/@core/preferences/src/config.ts 与 packages/@core/preferences/src/types.ts),你可按需调整切换按钮的挂载位置。

远程加载语言包

::: tip 提示 通过项目自带的request工具进行接口请求时,默认请求头中会带上 Accept-Language,服务端可根据该请求头对接口数据做动态国际化处理,实现"文案本地化 + 数据按语言下发"的双层国际化。 :::

每个应用都拥有独立的语言包,可以覆盖通用语言配置;你也可以通过远程接口加载语言包,只需修改对应应用src/locales/index.ts中的loadMessages方法:

async function loadMessages(lang: SupportedLanguagesType) { const [appLocaleMessages] = await Promise.all([ // Modify here to load data via a remote interface localesMap[lang](), loadThirdPartyMessage(lang), ]); return appLocaleMessages.default; }

这里localesMap[lang]()负责加载应用本地语言包(Promise.all保证与第三方语言包并行加载),你可以将这一行替换为远程接口调用(如fetch(/i18n/${lang}.json)),返回的 JSON 结构需与本地语言包一致。playground的实现见 playground/src/locales/index.ts,注释中同样标注了"这里也可以改造为从服务端获取翻译数据"。

第三方语言包

不同应用使用的第三方组件库或插件的国际化方式可能不一致,需要差别处理。如果你需要引入第三方语言包,可以在对应应用src/locales/index.ts中修改loadThirdPartyMessage方法。以 dayjs 为例(摘自 playground/src/locales/index.ts):

/** * Load the dayjs language pack * @param lang */ async function loadDayjsLocale(lang: SupportedLanguagesType) { let locale; switch (lang) { case 'zh-CN': { locale = await import('dayjs/locale/zh-cn'); break; } case 'en-US': { locale = await import('dayjs/locale/en'); break; } case 'zh-TW': { locale = await import('dayjs/locale/zh-tw'); break; } // Default to using English default: { locale = await import('dayjs/locale/en'); } } if (locale) { dayjs.locale(locale); } else { console.error(`Failed to load dayjs locale for ${lang}`); } }

playground中还演示了 Ant Design Vue(antdv-next)组件库的语言包加载:通过import('antdv-next/dist/locale/en_US')zh_CN等动态导入并赋值给响应式antdLocale,未打包对应语言包的语言会回退到en-US,避免残留上一次的语言(见 playground/src/locales/index.ts)。其他应用(apps/web-antdapps/web-eleapps/web-naiveapps/web-tdesignapps/web-antdv-next)都有各自的src/locales/index.ts,可按相同的模式接入 Element Plus、Naive UI、TDesign 等组件库的语言包。

移除国际化

首先需要说明:官方并不推荐移除国际化,因为国际化是一个良好的开发习惯。但如果你确实需要移除,可以直接使用中文文案并保留项目自带语言包,整体开发体验不会受影响。移除步骤如下:

  1. 隐藏界面上的语言切换按钮,见上文 界面切换语言功能;

  2. 修改默认语言,见上文 配置默认语言;

  3. 关闭vue-i18n的警告提示,在src/locales/index.ts文件内将missingWarn修改为false

    async function setupI18n(app: App, options: LocaleSetupOptions = {}) { await coreSetup(app, { defaultLocale: preferences.app.locale, loadMessages, missingWarn: !import.meta.env.PROD, // [!code --] missingWarn: false, // [!code ++] ...options, }); }

    默认情况下missingWarn在非生产环境开启(!import.meta.env.PROD),当代码中引用的翻译 key 在某语言包中缺失时,会在控制台打印[intlify] Not found 'xxx' key in 'yyy' locale messages.警告(缺省处理逻辑见 packages/locales/src/i18n.ts,开关类型定义见 packages/locales/src/typing.ts)。由于你仍在使用中文文案,将missingWarn置为false即可消除所有缺失 key 警告。

小结

Vue Vben Admin 的国际化体系以@vben/locales为通用底座、以各应用的src/locales为业务扩展层,通过偏好设置驱动默认语言、按需懒加载语言包、模块增强扩展类型、订阅机制驱动界面语言列表,形成了一条从"配置 → 加载 → 使用 → 扩展 → 远程化 → 移除"的完整链路。无论是仅切换中英文、接入第三语言、还是对接远程翻译服务,你都可以按本文的步骤在对应应用中直接落地。

【免费下载链接】vue-vben-adminA modern vue admin panel built with Vue3, Shadcn UI, Vite, TypeScript, and Monorepo. It's fast!项目地址: https://gitcode.com/GitHub_Trending/vu/vue-vben-admin

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询