国际化现在是很多项目的标准,所以我也在新项目中尝试一下国际化。这里我记录一下我使用vue-i18n的过程。
首先安装vue-i18n。
src目录下新建language文件夹,当然名字可以自己起。
其中除了index.ts是各个语言包文件,建议按照国际惯例命名文件。每个语言包里的key必须完全一致,而值则是对应语言的文字信息。以下分别是中文和英文的语言包。
重点就是index.ts文件了,由于需要实现按需引用,而且不是项目一开始加载所有语言包,所以相对复杂一点。需要使用到vite的动态引用模块功能。
useStore().config.lang.defaultLang,根据store中的默认语言,加载不同的语言包。暴露出registerI18n方法。
import { Composer, createI18n, I18n } from 'vue-i18n'
import { App } from 'vue'
import useStore from '@/stores'
export let i18n: {
global: Composer
}
/**
* 语言插件,需要在main中传递app对象
*/
export const registerI18n = async (app: App) => {
const defaultLang = useStore().config.lang.defaultLang
const path = `./${defaultLang}.ts`
let defaultLocal: anyObj = {}
/**
* 因为所有 import.meta.glob 的参数都必须以字面量传入。你 不 可以在其中使用变量或表达式。只能通过if来判断
* @link https://cn.vitejs.dev/guide/features.html#dynamic-import
*/
if (defaultLang === 'zh-cn') {
defaultLocal = import.meta.glob(`./zh-cn.ts`, { eager: true })
}
else if (defaultLang === 'en') {
defaultLocal = import.meta.glob(`./en.ts`, { eager: true })
}
else if (defaultLang === 'ja') {
defaultLocal = import.meta.glob(`./ja.ts`, { eager: true })
}
const messages = {
[defaultLang]: (defaultLocal[path] as anyObj).default
}
document.querySelector('html')?.setAttribute('lang', defaultLang) // 设置html中lang属性
// 不能把createI18n里的对象独立出来,必须直接把对象放在构造函数里
i18n = createI18n({
locale: defaultLang || 'zh-cn',
legacy: false, // 组合式api
globalInjection: true, // 挂载$t,$d等到全局
fallbackLocale: 'zh-cn',
messages
})
app.use(i18n as I18n)
}
然后main项目中,传递app对象
const setup = async () => {
const app = createApp(App)
app.use(pinia)
await registerI18n(app)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.use(router)
//app.use(i18n)
app.mount('#app')
}
setup()
最后,新建一个translate组件,使用下拉框来切换语言。
<!-- 语言切换组件 -->
<template>
<el-dropdown trigger="click" :size="props.size === 'mini' ? 'small' : props.size">
<i class="bi bi-translate text-white" :class="fontSize"></i>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-for="item in config.$state.lang.langArray" :key="item.name"
@click=" config.setDefaultLang(item.name as LocaleType)">{{ item.value
}}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<script setup lang="ts">
import useStore from '@/stores'
const { config } = useStore()
其中,config.setDefaultLang方法,就是更改store中的默认语言,具体实现逻辑,就请根据自己项目实际情况来切换了,我的代码如下。
/**
* 设置系统语言
* @param lang
* @param isReload 是否需要刷新页面,默认true
*/
setDefaultLang(lang: LocaleType, isReload = true) {
this.$state.lang.defaultLang = lang
if (isReload)
location.reload()
}
一定要刷新一下页面哦,我使用的是pinia,做了location持久化,所以下次访问后也会显示默认语言。
最后在需要使用多语言的界面,使用t(key)这样的形式显示文字。
import { i18n } from '@/language'
const { t } = i18n.global
<ElFormItem :label="t('login.code')" prop="code">
看看效果吧。