前情提示:这只是我个人的写法,可能不太符合你们的习惯,请酌情参考
最近项目里要配置国际化翻译,我就来用vue-i18n配置了
首先我们项目是vue3,框架是elementPlus,一个个来
第一步:
安装vue-i18n插件
npm install vue-i18n
我的目前是"vue-i18n": "^11.1.5",
第二步:
在src目录下建一个languages文件夹,里面包含index.js,zh.json,en.json
index.js内容
import { createI18n } from 'vue-i18n'
import Cookies from "js-cookie"
import zh from './zh.json'
import en from './en.json'
const currentLanguage = Cookies.get("language") || 'zh'
export const i18n = createI18n({
locale: currentLanguage,
legacy: false, // 修复组件引入i18n时vite脚手架报错的问题
globalInjection: true, // 全局注册 $t
messages: {
zh,
en
}
})
export const t = i18n.global.t
这里缓存语言类型是用的js-cookie,我本意是想用localStorage的,但是这个项目不是我建的,别人搭了基础框架,我也懒得改了,换成localStorage是完全可以的
zh.json
{
"账号": "账号",
"密码": "密码",
"语言": "语言",
"请输入账号": "请输入账号",
"请输入密码": "请输入密码",
"请选择语言": "请选择语言",
"记住密码": "记住密码",
"自动登录": "自动登录",
"登录": "登录",
"登录中": "登录中",
"立即注册": "立即注册"
}
en.json
{
"账号": "account",
"密码": "password",
"语言": "language",
"请输入账号": "please enter your account",
"请输入密码": "please enter your password",
"请选择语言": "please select language",
"记住密码": "remember password",
"自动登录": "auto login",
"登录": "Login",
"登录中": "Login in",
"立即注册": "register now"
}
这里我用的的key是中文,这里就是你们要酌情考虑的地方,我知道一般都是用英文单词做key,但是我以前做过国际化配置,用的也是英文单词做key,发现一个问题,vue文件里全是英文单词,我英语又不算好,想根据页面上的中文定位文件里对应的位置,真的非常难找啊
痛定思痛,决定还是用中文当key
还有就是一般都是有层级的,比如这样
{
"header": {
"title": "检测系统",
"home": "首页",
"systemConfiguration": "系统配置",
"inspectionSettings": "检测配置",
"faultConfiguration": "故障配置",
"logs": "日志"
}
}
但是我之前做也是,发现相同的太多了,改的时候也不知道要不要都改,最后我还是决定不用层级,简洁很多,编译器会自动检测key有没有重复的,有的话会用黄色波浪线提示你,注意下即可
我想到一种情况,比如相同的汉字代表不同的意思,比如“分”,可能是分数,可能是分钟,那怎么办呢?我目前的想法是这样的
{
"分(分数)": "point",
"分(分钟)": "minute",
}
小提示:vue-i18n一些小技巧可以参考这篇文章,我觉得很够用了
vue i18n国际化$t、$tc、$te、$d、$n用法_i18n $t-优快云博客
特别是动态翻译
第三步:
在main.js中引用
import { createApp } from 'vue'
import { i18n } from './languages/index'
const app = createApp(App)
app.use(i18n)
第四步:
本地持久化,在store里面新建locales.js
locales.js内容
import Cookies from 'js-cookie'
import { i18n } from '@/languages/index'
const useLocaleStore = defineStore(
'locale',
{
state: () => ({
language: Cookies.get('language') || 'zh', // element-ui 语言
}),
actions: {
setLocale(lang) {
this.language = lang
i18n.global.locale.value = lang
Cookies.set("language", lang, { expires: 30 })
}
}
}
)
export default useLocaleStore
我这里是Pinia,不是vuex,Pinia 简化了状态管理,移除了 mutations
的概念,actions
既可以处理同步操作,也能处理异步操作,并且可以直接修改 state
第五步:
显示语言切换功能
<el-form-item prop="language" :label="$t('语言')">
<el-select v-model="loginForm.language" placeholder="请选择语言" @change="handleChange">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
import useLocaleStore from '@/store/modules/locales'
const localeStore = useLocaleStore()
const options = [
{
value: 'zh',
label: '中文',
},
{
value: 'en',
label: 'English',
}
]
const handleChange = (val) => {
localeStore.setLocale(val)
}
第六步:
1.在vue文件中使用,直接使用$t
2.在<script>中,先引用再使用,用的是t
3.在js中,和2一样,先引用再使用
当然,如果你在vue文件中,引用了import { t } from '@/languages/index',你也可以在html上使用t,但我的建议还是不要这样,因为你要是忘记引用,就会报错的
第七步:
这里其实是注意事项,很重要
router文件夹里的文件,一定不要直接引用import { t } from '@/languages/index',然后使用t翻译
在 Vue 项目里,路由配置通常是静态加载的,初始化时就确定了路由元信息(meta)里的 title。即便后续语言切换,由于路由配置没有重新渲染,title 不会更新。
解决办法就是:
不直接在路由配置里写死翻译,而是在渲染菜单栏时动态获取翻译。例如在菜单栏组件里,使用 vue-i18n
的 t
函数获取翻译。
在菜单栏组件里翻译
<template #title>
<!-- 动态获取翻译 -->
<span>{{ $t(route.meta.title) }}</span>
</template>
第八步:
上面是vue3里的用法,下面来谈elementPlus的国际化配置
Element Plus 提供了一个 Vue 组件 ConfigProvider 用于全局配置国际化的设置。
在App.vue里
<template>
<el-config-provider :locale="currentLocale">
<router-view />
</el-config-provider>
</template>
<script setup>
import { ref, computed, watch } from 'vue'
import useLocaleStore from '@/store/modules/locales'
import zhCn from "element-plus/es/locale/lang/zh-cn";
import en from "element-plus/es/locale/lang/en";
const localeStore = useLocaleStore()
const currentLocale = computed(() => {
switch (localeStore.language) {
case 'zh':
return zhCn;
case 'en':
return en;
default:
return zhCn;
}
})
</script>
还有个问题:elementPlud表单校验提示不生效问题
这个我是参考这篇文章Vue 3 国际化实战:支持 Element Plus 组件和语言持久化_elementplus 国际化-优快云博客
我是这么写的
const loginRules = computed(() => {
return {
loginName: [{ required: true, trigger: "blur", message: t('请输入账号') }],
loginPassword: [{ required: true, trigger: "blur", message: t('请输入密码') }],
}
})
computed 用于创建计算属性,它会根据依赖的响应式数据自动更新。当使用 computed 定义 loginRules 时,computed 会追踪内部使用的响应式数据(如 vue-i18n 中的 locale)。当语言切换时,locale 发生变化,computed 属性会重新执行计算函数,从而重新调用 t() 函数获取最新的翻译内容。
所以记得使用computed
综上就是我在vue3项目里配置vue-i18n的全部过程了,经过一些个人取舍和更改,希望对你们有所帮助