Vue3 + js + element-plus 项目实战国际化
1 安装依赖
npm install vue-i18n@next
2 创建语言文件
// src/lang/language/en.js
export default {
lang: {
changeLanguageSuccess: "Language changed successfully!",
language: "English",
china: "China",
spain: "Spain",
english: "English",
},
login: {
title: "OK Cloud Management System",
registro: "Registro",
inputName: "Please enter your name",
inputPassword: "Please enter your password",
welcome: "Welcome",
username: "Username",
password: "Password",
confirmPassword: "Confirm Password",
solicitar: "Solicitar",
},
tips: {
inputName: "Please enter your name",
inputPassword: "Please enter your password",
userNameSize: "Username length 3-10 characters",
passwordSize: "The password must be 6-15 non-blank characters",
},
message: {
successLogin: "login successful!",
},
}
3 配置 i18n 国际化入口文件
import { createI18n } from "vue-i18n"
import zh from "./language/zh.js"
import en from "./language/en.js"
import es from "./language/es.js"
const messages = {
zh: zh,
en: en,
es: es,
}
const i18n = createI18n({
legacy: false,
locale: 'zh',
fallbackLocale: 'zh',
messages: messages,
})
export default i18n
4 配置element-plus
import en from 'element-plus/es/locale/lang/en'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import es from 'element-plus/es/locale/lang/es'
export const elementLocales = {
en : en,
es : es,
zh : zhCn,
}
5 全局挂载 i8n 组件
import i18n from '@/lang/index'
app.use(i18n)
6 pinia 状态管理
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useLanguageStore = defineStore('language', () => {
const supportedLanguages = ['zh', 'en', 'es']
function initLanguage() {
const browserLang = navigator.language?.toLowerCase().split('-')[0]
const storyData = localStorage.getItem('app-language')
const localStoryLanguage = storyData ? JSON.parse(storyData).language : null;
const res = localStoryLanguage || browserLang || 'zh'
return res
}
const language = ref(initLanguage())
function setLanguage(lang) {
if (supportedLanguages.includes(lang)) {
language.value = lang
return true
}
return false
}
return {
language,
setLanguage
}
}, {
persist: {
key: 'app-language',
storage: localStorage,
}
})
7 配置入口文件
// src/App.vue
<template>
<el-config-provider :locale="elementLocales[lang]">
<router-view></router-view>
</el-config-provider>
</template>
<script setup>
import { useLanguageStore } from '@/store/modules/language'
import { elementLocales } from '@/lang/element-plus-i18n'
import { useI18n } from 'vue-i18n'
import { computed } from 'vue';
const languageStore = useLanguageStore()
let lang = computed(() => languageStore.language)
const {locale} = useI18n()
locale.value = lang.value
</script>
8 封装切换语言组件
<template>
<el-dropdown placement="bottom-end" @command="selectLanguage">
<span class="el-dropdown-link">
<strong>{{ $t('lang.language') }}</strong>
<svg-icon :icon-class="languageStore.language" />
<el-icon><CaretBottom/></el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="zh" >中文</el-dropdown-item>
<el-dropdown-item command="es" >Español</el-dropdown-item>
<el-dropdown-item command="en" >English</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<script setup name="LangSelect">
import { useI18n } from 'vue-i18n'
import { useLanguageStore } from '@/store/modules/language';
import { CaretBottom } from '@element-plus/icons-vue';
import { changeLanguage } from '../../api/login';
import { ElMessage } from 'element-plus';
const languageStore = useLanguageStore()
console.log("当前的语言状态是:",languageStore.language)
const {locale} = useI18n()
const {t} = useI18n()
const javaLang = {
zh : "zh_CN",
es : "es_ES",
en : "en_US"
}
const selectLanguage = (key) => {
languageStore.setLanguage(key)
locale.value = key
changeLanguage(javaLang[key]).then(res => {
ElMessage.success(t('lang.changeLanguageSuccess'))
})
}
</script>
<style lang="scss" scoped>
.el-dropdown-link{
height: 100%;
margin-left: 10px;
margin-right: 10px;
padding: 0;
display: flex;
align-items: center;
// color: $layout-font-color;
// font-size: 20px;
border: none !important; // 隐藏组件el-dropdown 的边框
outline: none !important; // 隐藏组件el-dropdown 的边框
.svg-icon{
margin-left: 5px;
font-size: 40px;
}
}
</style>
9 使用多语言
9.1 vue模板中使用
<template>
<div>
<h1>{{ $t('message.welcome') }}</h1>
<el-button>{{ $t('buttons.submit') }}</el-button>
</div>
</template>
<script setup>
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
</script>
9.2 Script 中使用
<script setup>
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
console.log(t('message.hello'))
</script>
9.3 Js文件中使用(全局)
import i18n from
const t = i18n.global.t
router.beforeEach((to, from, next) => {
...
if (to.meta.title) {
const title = t(to.meta.title)
useSettingsStore().setTitle(title) // 存储到Store(设置网页标题)
}
...
}
9.4 路由标题国际化
9.4.1 固态路由维护
const routes = [
{
path: '/home',
component: () => import('@/views/home'),
meta: {
title: 'route.home'
}
}
]
9.4.2 动态路由维护
9.4.3 维护组件展示路由
router.beforeEach((to, from, next) => {
...
if (to.meta.title) {
const title = i18n.global.t(to.meta.title)
useSettingsStore().setTitle(title)
}
...
}
{{ $t(item.meta.title) }}
import { useI18n } from 'vue-i18n'
const { t } = useI18n() ;
10 嵌套翻译
1 引用翻译
`${t('importData.importOrderDetail')}_${new Date().getTime()}.xlsx`
2 嵌套翻译
2.1 翻译字段
importData.messageSuccessError:'成功条数 {count}, 失败条数 {error}'
2.2 翻译引用
t('importData.messageSuccessError',
{count: result.data.successCount, error: result.data.failedList.length}
)