国际化
国际化功能全部在前端处理,提示消息可以通过状态码完成国际化翻译。前端框架内置了国际化功能,并对 Element Plus 完成了国际化配置。国际化的功能是基于 Vue I18n 完成。
注意
项目中并未对 Vue I18n 的日期、数字等功能进行配置,请勿使用!如有相关需求请与作者联系。
IDE 插件安装
VS Code 插件安装
在 vscode 插件商店搜 lokalise.i18n-ally 进行安装,可以带来更友好的国际化提示

WebStorm 插件安装
在 WebStorm 插件商店搜 i18n Ally 进行安装,可以带来更友好的国际化提示

使用快捷键 Ctrl Alt S 打开配置页面进行插件设置

- 在设置选择
Project settings Translation storage使用NamespacedTranslations directory设置为$PROJECT_DIR$/localesDefault locale设置为zh-CNNamespaces设置为messagesFile name template设置为%locale%.ymlJavaScript/TypeScript Default template设置为t('%key%', %map%)
国际化数据存储
重要
多语言文件存储分为全局语言文件、私有语言文件。请勿将全部语言文件都放在全局语言文件中,请自行创建私有语言文件。
全局语言文件
只存储通用的语言数据,各个模块的语言数据请创建私有语言文件进行存储。
- 全局语言文件统一存储在项目根目录下的
locales目录下,以json格式进行的存储。 - 中文统一存储在
zh-CN.json中,英文统一存储在en.json文件中。 - 支持嵌套结构,可以根据不同的分类进行存储,方便维护与查找。
- 命名规则使用
camelCase,即小驼峰。

私有语言文件
私有语言文件分为两种:模块语言文件、组件语言文件。
警告
- 如果某个多语言需全局访问,可以将其放在全局中,请勿使用私有模型,否则将无法访问。
- 某些多语言可能无法在 setup 中使用,这种情况必须放在全局语言中(即:无法使用
useI18n的情况下)。
模块语言文件
在每个模块下创建自己的多语言文件,下面我以 workflow 模块为例:
在
src/modules/workflow/locales目录下创建语言文件,以json存储。例如:zh-CN.json创建
src/modules/workflow/i18n.ts文件来初始化多语言数据。代码实例如下:import { createI18nMessages } from '@/config/i18n'; import en from './locales/en.json'; import zhCN from './locales/zh-CN.json'; import { useI18n } from 'vue-i18n'; /** 工作流模块多语言处理 */ export function useWorkflowI18n() { return useI18n({ messages: createI18nMessages(zhCN, en) }); }由于使用了
useI18n所以useWorkflowI18n只能在setup内使用useWorkflowI18n返回的t函数的数据会继承全局的数据,所以这个t函数可以使用全局语言文件内的语言数据为了防止多语言 key 重复,JSON 的基础 key 以模块名为基础,例如:
{ "workflow": { "flowDesigner": { "multiInstanceType": "多任务处理方式", "completionCondition": "完成条件" } } }
组件语言文件
组件语言文件的使用方式与模块语言文件的使用方式一样,当发现某个组件的多语言数据比较庞大并且在模块内部没有通用性,那么可以在组件内拆出一个组件语言文件。下面我以用户偏好配置为例:
目录结构如下:
user-preference
├── locales
│ ├── zh-CN.json
│ └── en.json
├── i18n.ts
└── UserPreference.vuei18n.ts 代码,与模块语言文件使用方式一样,只是方法名不同。
import { createI18nMessages } from '@/config/i18n';
import en from './locales/en.json';
import zhCN from './locales/zh-CN.json';
import { useI18n } from 'vue-i18n';
/** 个人偏好多语言处理 */
export function useUserPreferenceI18n() {
return useI18n({ messages: createI18nMessages(zhCN, en) });
}zh-CN.json 文件如下,这里也是要注意 userPreferenceSetting 不要冲突。
{
"userPreferenceSetting": {
"preference": "偏好设置",
"notificationType": {
"label": "系统通知方式",
"desc": "关闭:屏蔽一切通知消息\n站内通知:有新消息时会在站内弹窗提醒\n系统通知:有新消息时会在操作系统上发送通知(必要满足条件:windows 11 或 macOS 操作系统、浏览器支持、拥有 https 以及域名、开启了通知权限)\n站内及系统通知:同时开启【站内通知】和【系统通知】",
"option": {
"off": "关闭",
"inApp": "站内通知",
"system": "系统通知",
"inAppAndSystem": "站内及系统通知"
}
},
"newTabOpenType": {
"label": "新标签页打开方式",
"desc": "当前活动标签后:当打开新的标签页时,会出现在当前选中的标签页之后\n最后一个标签后:当打开新的标签页时,会出现在目前所有标签页的最后面",
"option": {
"activeAfter": "当前活动标签后",
"last": "最后一个标签后"
}
}
}
}基础用法
本节只介绍基本用法,例如参数替换(可以传入动态参数,例如:密码输入错误 {n} 次,账号将被锁定)等高级功能请查询 官网文档
Vue 模板中使用
在模板中,我们使用 Vue I18n 的全局方法 $t 进行动态获取本地化的数据。
<el-select>
<el-option value="auto" :label="$t('theme.auto')" />
<el-option value="dark" :label="$t('theme.dark')" />
<el-option value="light" :label="$t('theme.light')" />
</el-select>Vue setup 中使用
可以使用 Vue I18n 提供的 useI18n() 方法解构出 t 方法进行动态获取本地化数据。
<script setup lang="ts">
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const auto = ref(t('theme.auto'));
</script>提示
切记 useI18n() 只能用在 setup 中使用
TypeScript 全局使用
由于 useI18n() 只能用在 setup 中使用,所以当你写一些工具类时可能有些麻烦,这里有两种方案可参考。
工具类的使用需要在 setup 中先解构
/**
* i18n工具类
*/
export function i18nUtils() {
// useI18n必须写在setup中,故要写在这里,在setup中解构此方法,拿到switchI18n进行使用
const { locale, t } = useI18n();
// 全部支持的语言类型
const locales = {
'zh-CN': t('locale.zhCN'),
en: t('locale.en'),
};
/**
* 语言切换
* @param lang 支持字符串 zh-CN、en
*/
const switchI18n = (lang: SwitchI18nLang = 'zh-CN') => {
if (Object.keys(locales).indexOf(lang) > -1) {
locale.value = lang;
localStorage.setItem('locale', lang);
document.querySelector('html')?.setAttribute('lang', lang);
} else {
console.warn(`切换的语言不支持,默认切换为中文 lang=${lang}`);
locale.value = 'zh-CN';
localStorage.setItem('locale', 'zh-CN');
document.querySelector('html')?.setAttribute('lang', 'zh-CN');
}
};
return { switchI18n, locales };
}
// 我需要这样使用 locales
const { locales } = i18nUtils();工具类需要在任意位置使用
类似项目的的 ajaxUtils,我是用抽象类定义了一个工具类,并没有使用函数的形式,所以就需要使用 i18n 的全局变量。
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
import { authUtils } from '../auth/auth-utils';
import router from '../../router';
import { i18n } from '@/config/i18n';
import { ResultVO } from './ajax-types';
const { t } = i18n.global;
export abstract class BaseAjaxUtils {
/**
* Axios 实例,实现类可以继承此方法来创建自己的 baseURL
* @protected
*/
protected instance: AxiosInstance = axios.create();
protected constructor() {
// 添加响应拦截器
this.instance.interceptors.response.use(
function (response) {
// 请求成功直接提取接口返回的内容
return response.data;
},
function (error) {
try {
if (error.response.status === 401) {
msgUtils.warning(t('msg.warning.loginTimeoutReLogin'));
router.replace({ name: 'Login' });
} else if (error.response.status === 403) {
msgUtils.warning(t('msg.warning.forbidden'));
console.warn(`接口权限不足,请求url=${error.config.url}`);
}
} catch (e) {
console.error(e, 'axios异常拦截器处理异常,可以忽略此错误');
}
return Promise.reject(error);
},
);
}
}