国际化
如果你使用的 vscode 开发工具,则推荐安装 I18n-ally 这个插件
I18n-ally 插件
安装了该插件后,你的代码内可以实时看到对应的语言内容
配置默认语言
在 src/settings/localeSetting.ts 内可以配置默认语言
export const LOCALE: { [key: string]: LocaleType } = {
ZH_CN: 'zh_CN',
EN_US: 'en',
};
export const localeSetting: LocaleSetting = {
// 是否显示语言选择器
showPicker: true,
// 当前语言
locale: LOCALE.ZH_CN,
// 默认语言
fallback: LOCALE.ZH_CN,
// 允许的语言
availableLocales: [LOCALE.ZH_CN, LOCALE.EN_US],
};
// 配置语言列表
export const localeList: DropMenu[] = [
{
text: '简体中文',
event: 'zh_CN',
},
{
text: 'English',
event: 'en',
},
];
配置
在 src/locales/setupI18n.ts 内引入的 i18n 这个无需修改
语言文件
在 src/locales/lang/ 可以配置具体的语言
# locales/lang/
# 中文语言
zh_CN:
component: 组件相关
layout: 布局相关
routes: 路由菜单相关
sys: 系统页面相关
en: 同上
语言导入逻辑说明
- 初始化
在 src/locales/setupI18n 内的根语言文件可以看到
const defaultLocal = await import(`./lang/${locale}.ts`);
这会导入 src/locales/lang/{lang}.ts
文件语言包,此文件会导入对应语言下的所有文件。
import { genMessage } from '../helper';
import antdLocale from 'ant-design-vue/es/locale/zh_CN';
import momentLocale from 'moment/dist/locale/zh-cn';
const modules = import.meta.globEager('./zh_CN/**/*.ts');
export default {
message: {
...genMessage(modules, 'zh_CN'),
antdLocale,
},
momentLocale,
momentLocaleName: 'zh-cn',
};
并将其按相应的目录结构转化为多层级的
例:
lang/zh_CN/components/modal.ts
的文件内容为
{
title: '标题';
}
则在使用的使用直接使用 t('components.modal.title')
进行获取。
这样做的好处在于更容易管理大型项目的多语言。如果不需要分模块划分,可以直接自己手动导入即可。
使用
引入项目自带的 useI18n
注意不要引入 vue-i18n 的 useI18n
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
const title = t('components.modal.title');
切换语言
切换语言需要使用 src/locales/useLocale.ts
import { useLocale } from '/@/locales/useLocale';
const { changeLocale } = useLocale();
changeLocale('en');
新增
语言文件
在 src/locales/lang/ 增加对应语言的文件即可
新增语言
目前项目自带的语言只有 zh_CN
和 en
两种
如果需要新增,按以下操作即可
- 在 src/locales/lang/ 下新增相应的语言目录及语言文件并引入 引入 ant-design-vue 和 moment 对应的语言包
- 在 types/config.d.ts 内加上预览类型定义
- 在 src/settings/localeSetting.ts 修改语言配置
远程读取语言数据
目前项目会在 src/main.ts
内等待 setupI18n
这个函数执行完之后才会渲染界面,所以只需在 setupI18n 内发送 ajax 请求,将对应的数据设置到 i18n 实例上即可
// src/main.ts
await setupI18n(app);
app.mount('#app', true);
setupI18n 函数
如下所示,这里会先设置一个默认语言,默认语言可以设置在本地,也可以在这里等待接口返回默认语言
// setup i18n instance with glob
export async function setupI18n(app: App) {
const options = await createI18nOptions();
i18n = createI18n(options) as I18n;
app.use(i18n);
}
async function createI18nOptions(): Promise<I18nOptions> {
const locale = localeStore.getLocale;
// 这里改成接口获取
const defaultLocal = await import(`./lang/${locale}.ts`);
const message = defaultLocal.default?.message ?? {};
return {
legacy: false,
locale,
fallbackLocale: fallback,
messages: {
[locale]: message,
},
availableLocales: availableLocales,
sync: true,
silentTranslationWarn: true,
missingWarn: false,
silentFallbackWarn: true,
};
}
changeLocale 函数
当手动切换语言的时候会触发 useLocale
函数,useLocale 也是异步函数,只需等待接口返回响应的数据后,再进行设置即可
async function changeLocale(locale: LocaleType) {
const globalI18n = i18n.global;
const currentLocale = unref(globalI18n.locale);
if (currentLocale === locale) return locale;
if (loadLocalePool.includes(locale)) {
setI18nLanguage(locale);
return locale;
}
// 这里改成接口获取
const langModule = ((await import(`./lang/${locale}.ts`)) as any).default as LangModule;
if (!langModule) return;
const { message, momentLocale, momentLocaleName } = langModule;
globalI18n.setLocaleMessage(locale, message);
moment.updateLocale(momentLocaleName, momentLocale);
loadLocalePool.push(locale);
setI18nLanguage(locale);
return locale;
}