Skip to content

国际化

项目已经集成了 Vue i18n,并且已经配置好了中文和英文的语言包。

IDE 插件

如果你使用的 vscode 开发工具,则推荐安装 i18n Ally 这个插件。它可以帮助你更方便的管理国际化的文案,安装了该插件后,你的代码内可以实时看到对应的语言内容:

配置默认语言

只需要覆盖默认的偏好设置即可,在对应的应用内,找到 src/preferences.ts 文件,修改 locale 的值即可:

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

动态切换语言

切换语言有两部分组成:

  • 更新偏好设置
  • 加载对应的语言包
ts
ts
import type { SupportedLanguagesType } from '@vben/locales';
import { loadLocaleMessages } from '@vben/locales';
import { updatePreferences } from '@vben/preferences';

async function updateLocale(value: string) {
  // 1. 更新偏好设置
  const locale = value as SupportedLanguagesType;
  updatePreferences({
    app: {
      locale,
    },
  });
  // 2. 加载对应的语言包
  await loadLocaleMessages(locale);
}

updateLocale('en-US');

新增翻译文本

注意

  • 请不要将业务翻译文本放到 @vben/locales 内,这样可以更好的管理业务和通用的翻译文本。
  • 有多个语言包的情况下,新增翻译文本时,需要在所有语言包内新增对应的文本。

新增翻译文本,只需要在对应的应用内,找到 src/locales/langs/,新增对应的文本即可,例:

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

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

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

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

使用翻译文本

通过 @vben/locales,你可以很方便的使用翻译文本:

在代码中使用

vue
vue
<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>

新增语言包

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

  • packages/locales/src/langs 目录下新增对应的语言包文件夹和文件,例:zh-TW/*.json,并翻译对应的文本。

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

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

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

    提示

    顶部的 re-export 不可省略:它使文件成为模块,declare module 才是模块增强;否则会被视为环境模块声明,遮蔽原模块导致其下所有类型丢失。同时应用需要声明 @vben-core/typings 依赖(monorepo 内部包通常已具备)。

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

    ts
    ts
    import { setSupportLanguages, SUPPORT_LANGUAGES } from '@vben/constants';
    
    setSupportLanguages([
      ...SUPPORT_LANGUAGES,
      { label: '繁體中文', value: 'zh-TW' },
    ]);
  • 如果应用使用了 dayjs、组件库等第三方库,在 src/locales/index.ts 的语言加载逻辑中补充对应的语言包分支。

到这里,你就可以在项目内使用新增的语言包了,SupportedLanguagesType 联合类型会自动包含新语言,所有相关 API 均获得完整的类型约束。

界面切换语言功能

如果你想关闭界面上的语言切换显示按钮,在对应的应用内,找到 src/preferences.ts 文件,修改 locale 的值即可:

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

远程加载语言包

提示

通过项目自带的request工具进行接口请求时,默认请求头里会带上 Accept-Language ,服务端可根据请求头进行动态数据国际化处理。

每个应用都有一个独立的语言包,它可以覆盖通用的语言配置,你可以通过远程加载的方式来获取对应的语言包,只需要在对应的应用内,找到 src/locales/index.ts 文件,修改 loadMessages 方法即可:

ts
ts
async function loadMessages(lang: SupportedLanguagesType) {
  const [appLocaleMessages] = await Promise.all([
    // 这里修改为远程接口加载数据即可
    localesMap[lang](),
    loadThirdPartyMessage(lang),
  ]);
  return appLocaleMessages.default;
}

第三方语言包

不同应用内使用的第三方组件库或者插件国际化方式可能不一致,所以需要差别处理。 如果你需要引入第三方的语言包,你可以在对应的应用内,找到 src/locales/index.ts 文件,修改 loadThirdPartyMessage 方法即可:

ts
ts
/**
 * 加载dayjs的语言包
 * @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;
    }
    // 默认使用英语
    default: {
      locale = await import('dayjs/locale/en');
    }
  }
  if (locale) {
    dayjs.locale(locale);
  } else {
    console.error(`Failed to load dayjs locale for ${lang}`);
  }
}

移除国际化

首先,不是很建议移除国际化,因为国际化是一个很好的开发习惯,但是如果你真的需要移除国际化,你可以直接使用中文文案,然后保留项目自带的语言包即可,整体开发体验不会影响。移除国际化的步骤如下:

  • 隐藏界面上的语言切换按钮,见:界面切换语言功能

  • 修改默认语言,见:配置默认语言

  • 关闭 vue-i18n的警告提示,在src/locales/index.ts文件内,修改missingWarnfalse即可:

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

贡献者

The avatar of contributor named as vben vben
The avatar of contributor named as 陆伯言 陆伯言
The avatar of contributor named as Dream Dream
The avatar of contributor named as vince vince

页面历史

基于 MIT 许可发布.