vue3和elementPlus里配置多语言切换vue-i18n

前情提示:这只是我个人的写法,可能不太符合你们的习惯,请酌情参考
最近项目里要配置国际化翻译,我就来用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的全部过程了,经过一些个人取舍和更改,希望对你们有所帮助

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值