vue3+element plus+vue-i18操作步骤
首先安装vue-i18n
npm install vue-i18n
或者
yarn add vue-i18n
如果配置文件没问题,报错vue-i18n的问题,大概是依赖的问题,vue-i18n更新最新
npm install vue-i18n@latest
或者
yarn add vue-i18n@latest
在vscode上安装i18n-ally插件
如图:
vscode的setting关于i18n-ally的配置
"i18n-ally.localesPaths": ["src/locales"],// 指定翻译文件存放的路径
"i18n-ally.keystyle": "nested",// 设置键的样式为嵌套(例如:foo.bar)
"i18n-ally.translate.engines": ["google","google-cn","deepl"],// 指定翻译时使用的引擎,可以使用 Google、Google-CN 或 DeepL
"i18n-ally.namespace": true,// 启用命名空间,这样可以将翻译按模块分组
"i18n-ally.enabledParsers": ["js","json"],// 指定允许的解析器,支持 js 和 json 文件
"i18n-ally.sortKeys": true,// 启用键排序,翻译键会按字母顺序排序
"i18n-ally.sourceLanguage": "zh-CN",// 设置源语言为中文(简体)
"i18n-ally.displayLanguage": "zh-CN",// 设置显示语言为中文(简体)
"i18n-ally.extract.keygenStyle": "camelCase",// 提取键名的风格为驼峰式(例如:fooBar)
"i18n-ally.enabledFrameworks": ["vue","react"],// 启用的框架,支持 Vue 和 React
项目文件目录
如图:
其中 en.json 和 zh-Cn.json 为翻译原件,index.js 则是我们需要配置的i18n参数文件
import { createI18n } from 'vue-i18n';
import { useStorage } from '@vueuse/core';
// 自定义语言文件
import zhCN from '@/locales/zh-CN.json';
import en from '@/locales/en.json';
import ele_zhCN from 'element-plus/es/locale/lang/zh-cn';
import ele_en from 'element-plus/es/locale/lang/en';
const messages = {
zhCN: {
...zhCN,
...ele_zhCN,
},
en: {
...en,
...ele_en,
},
};
const getLanguage = () => {
const language = useStorage('language', 'en');
if (language.value) {
return language.value;
}
return 'en';
};
// // const language = (navigator.language || 'zhCN').toLocaleLowerCase(); // 这是获取浏览器的语言
const i18n = createI18n({
legacy: true, // 是否使用 composition API 模式
// locale: localStorage.getItem('locales') || language.split('-')[0] || 'zhCN', // 首先从缓存里拿,没有的话就用浏览器语言, "zhCN",
locale: getLanguage(),
globalInjection: true, //允许全局使用$t()函数
fallbackLocale: 'zhCN', // 设置备用语言
messages,
});
export default i18n;
接着我们需要在主文件 main.js 引入
import i18n from './locales/index'; //国际化
app.use(i18n);
切换语言按钮
<template>
<el-dropdown trigger="click" @command="handleLanguageChange">
<div class="lang-select--style">
<svg-icon icon-class="language" />
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item :disabled="appStore.language === 'zhCN'" command="zhCN"> 中文 </el-dropdown-item>
<el-dropdown-item :disabled="appStore.language === 'en'" command="en"> English </el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<script setup>
import { useI18n } from 'vue-i18n';
import SvgIcon from '@/components/SvgIcon/index.vue';
import useAppStore from '@/store/modules/app';
const appStore = useAppStore();
const { locale } = useI18n();
const { proxy } = getCurrentInstance();
const message = {
zhCN: '切换语言成功!',
en: 'Switch Language Successful!',
}
const handleLanguageChange = (lang) => {
locale.value = lang;
appStore.changeLanguage(lang);
proxy.$modal.msgSuccess(message[lang]);
}
</script>
<style lang="scss" scoped>
.lang-select--style {
font-size: 18px;
line-height: 50px;
}
</style>
这里做了语言的缓存以及状态管理,主要是为了解决后续切换语言,刷新浏览器,页面语言被还原了
const useAppStore = defineStore('app', {
state: () => ({
language: useStorage('language', 'en'),
}),
actions: {
changeLanguage(val) {
this.language = val;
},
},
});
最终
<template>
<el-config-provider :locale="language === 'en' ? en : zhCN">
<router-view v-if="isActive" />
</el-config-provider>
</template>
<script setup>
import useSettingsStore from '@/store/modules/settings'
import { handleThemeStyle } from '@/utils/theme'
import i18n from "./locales";
import useAppStore from '@/store/modules/app';
import { watch } from 'vue';
const appStore = useAppStore();
const language = computed(() => appStore.language)
const zhCN = i18n.global.messages.zhCN
const en = i18n.global.messages.en
const isActive = ref(false)//用来解决el-form的校验在切换中英文后,还是原语言
//刷新页面
function reload() {
isActive.value = false
nextTick(() => {
isActive.value = true
})
}
//监听语言的切换,切换后刷新页面
watch(() => appStore.language, (newVal, oldVal) => {
if (newVal !== oldVal) {
reload()
}
// console.log("🚀 ~ language:", language.value)
}, { immediate: true })
onMounted(() => {
nextTick(() => {
// 初始化主题样式
handleThemeStyle(useSettingsStore().theme)
})
})
</script>
这里遇到一个问题,在 el-form 校验时,切换语言,发现还是前一个语言的校验,所以这里给 router-view 加上了 isActive 控制,相当于手动刷新
总结
问题
- i18n-ally插件的setting一定要配置对,不然不起作用
- 项目目录的语言包尽量用 .json 格式
- 切换语言一定要做缓存和状态管理
- 表单校验报错信息切换语言并不生效
补充
import i18n from '@/locales/index';
/**
* 获取国际化路由,如果不存在则原生返回
* @param title 路由名称
* @returns {string}
*/
export const translateRouteTitle = (title) => {
// 遍历对象,查找对应的key
for (const key in i18n.global.messages.zhCN.sideBar) {
if (i18n.global.messages.zhCN.sideBar[key] === title) {
return key;
}
}
};
这里是国际化路由的方法,应为路由返回的是中文,这里我拿中文去匹配对应的key值,应为我们在翻译时,用的是对应的key
$t('form.name')//标签属性内部的中文
{{$t('form.name')}} //内容
t('form.name') //vue文件的<script></script>使用需要引用
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
//在.js文件中使用
import i18n from '@/locales';
i18n.global.t('form.name')