先上需求:如何在不刷新页面的情况下,切换elementplus组件库的国际化
本人用到的插件:I18n,elementPlus,@intlify/vite-plugin-vue-i18n
首先:直接使用全局配置ConfigProvider组件
代码如下:
import zhCn from 'element-plus/lib/locale/lang/zh-cn';
<ElConfigProvider :locale="zhCn">
<RouterView></RouterView>
</ElConfigProvider>
嗯,这样就可以全局配置了,but这玩意儿是静态的,而且只能引用官方的国际化文件,并且无法切换。
顺便提下@intlify/vite-plugin-vue-i18n插件,vite.config.ts中的配置代码如下:
import path from 'path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueI18n from '@intlify/vite-plugin-vue-i18n'
export default defineConfig({
plugins: [
vue(), // you need to install `@vitejs/plugin-vue`
vueI18n({
// if you want to use Vue I18n Legacy API, you need to set `compositionOnly: false`
// compositionOnly: false,
// you need to set i18n resource including paths !
include: path.resolve(__dirname, '../locales/**')
})
]
})
这玩意儿可以直接加载整个文件夹内的配置文件,如
会自动加载locales文件夹中的四个json国际化文件。
新建一个lang.ts文件
import { createI18n } from 'vue-i18n';
import messages from '@intlify/vite-plugin-vue-i18n/messages';
const i18n = createI18n({
locale: 'en-US',
globalInjection: true,
messages,
});
export default i18n;
main.ts中使用国际化
// i18n
import i18n from './utils/lang';
...
app.use(i18n) // 直接使用即可
...
国际化简单的配置好了,那如何才能动态切换elementplus组件库的国际化呢
首先我们在App.vue中引用
import localesList from '@intlify/vite-plugin-vue-i18n/messages';
...
// 这里引用I18n
const { t, availableLocales, locale } = useI18n();
其次我们再新建一个计算属性 elementlocale
const toJson = (json: any, k: string) => {
const result: any = {};
// eslint-disable-next-line no-restricted-syntax
for (const key in json) {
if (Object.prototype.hasOwnProperty.call(json, key)) {
const element = json[key];
if (typeof element === 'object') {
result[key] = toJson(element, `${k}.${key}`)
} else {
result[key] = t(`${k}.${key}`);
}
}
}
return result;
};
const elementlocale = computed(()=>{
const obj = {
name: locale.value,
el: toJson(localesList[locale.value].lang.el)
};
return obj;
})
这里不得不说一下,为什么会有toJson这个函数,因为 @intlify/vite-plugin-vue-i18n/messages 获取到的国际化内容格式是这样的
对比了一下elementplus自带的国际化文件的数据
发现i18n国际化中多了一层source这个属性,debugger看了下源码,这里是直接返回一个函数,不是个字符串,导致之前怎么切换都无效果,所以这里我写了一个toJson函数转化了一下。
到这里就好了,把之前写的计算属性放到ConfigProvider中,后续只需要在其他页面更改locale.value即可,完整使用代码:
<script setup lang="ts">
import localesList from '@intlify/vite-plugin-vue-i18n/messages';
...
const { t, availableLocales, locale } = useI18n();
...
// i18n转json
const toJson = (json: any) => {
let result:any = {};
for (const key in json) {
if (Object.prototype.hasOwnProperty.call(json, key)) {
const element = json[key];
if(element.source){
result[key] = element.source;
}else{
result[key] = toJson(element);
}
}
}
return result;
}
// 计算属性,监听locale
const elementlocale = computed(()=>{
const obj = {
name: locale.value,
el: toJson(localesList[locale.value].lang.el)
};
return obj;
});
</script>
<template>
<ElConfigProvider :locale="elementlocale">
<RouterView></RouterView>
</ElConfigProvider>
</template>