网站:https://kazupon.github.io/vue-i18n/zh/
需求:点击语言切换的按钮进行切换即可,在缓存中存储,下次登录仍是上次的语言
本文完全是自己的需求,不能每个都一样,仅供参考,如果有问题随时指出。本人还是正在进步中~
整体逻辑
- 首先准备好各种文件
- 编写切换到按钮,缓存
- 配置语言文件
- 替换内容即可
安装
npm install vue-i18n
目录
...
- src
- i18n
+ locales // 多语言文件夹
+ en-US.json
+ zh-CN.json
+ rules // 规则文件夹
+ datetime.js // 时间格式化
+ number.js // 金钱格式化
+ constants.js // 常量
+ index.js // 入口文件夹
+ translation.js // 一些方法,存储语言,获取当前语言等
文件内容书写参考
env的文件:我的vue3项目中还定义的默认语言,以防止获取不到可以使用
VITE_DEFAULT_LOCALE = zh-CN
VITE_FALLBACK_LOCALE = en-US
- 语言文件
en-US.json 英文
{
// 这个common是根据项目的文件进行区分的,使用方式 $t('common.querySearch')
"common": {
"querySearch": "Search",
"queryReset": "Reset",
"queryInputPlhd": "Please Enter {name}",
"querySelectPlhd": "Please Select {name}","
},
"buyBulletin": {
"queryTitle": "Title",
"queryAccount": "Publishers"
}
}
zh-CN.json 中文
{
// 以管理系统中的搜索为例:使用方式 $t('common.querySearch')
"common": {
"querySearch": "搜索",
"queryReset": "重置",
"queryInputPlhd": "请输入{name}",
"querySelectPlhd": "请选择{name}",
},
"buyBulletin": {
"queryTitle": "公告标题",
"queryAccount": "发布人"
}
}
- 规则文件
rules/datetime.js 时间格式化,写的比较简单,没怎么用上,项目中组件的语言使用的element-plus自带的
const datetimeFormats = {};
['en-US', 'zh-CN'].forEach(locale => {
datetimeFormats[locale] = {
shortFormat: {
year:'numeric',month:'short', day:'numeric'
},
longFormat: {
year: 'numeric', month: 'short', day: 'numeric',
weekday: 'short', hour: 'numeric', minute: 'numeric',second: 'numeric'
}
}
})
export default datetimeFormats;
rules/number.js 数字的格式化,这个使用的是后端返回的数据,写的比较简单,可以根据需要扩展
export default {
"en-US": {
currencyFormat: {
style: "currency",
currency: "USD"
}
},
"zh-CN": {
currencyFormat: {
style: "currency",
currency: "CNY"
}
}
}
- 语言常量文件
export const LANGUAGES = {
"zh-CN": "简体中文",
"en-US": "English"
}
- Translation 所有的方法,属性文件
import i18n from "./index"
import { LANGUAGES } from "./constants";
const Translation = {
// 获取所有支持语言的对象
get supportedLocales() {
return LANGUAGES;
},
// 获取设置当前语言
get currentLanguage() {
return i18n.global.locale.value
},
set currentLanguage(value) {
i18n.global.locale.value = value
},
// 判断语言常量中支不支持当前参数的语言
isSupportedLocales(locale) {
return locale in Translation.supportedLocales
},
// 获取.env中默认的语言设置
get getEnvDefaultLocales() {
return import.meta.env.VITE_DEFAULT_LOCALE
},
// 获取用户浏览器默认的语言
getUserBrowserDefauleLanguage() {
const locale = navigator.language ? navigator.language : Translation.getEnvDefaultLocales
return {
locale,
localeNoRegion: locale.split('-')[0] //zh,en
}
},
// 获取用户缓存的语言
getUserLocalStorageLanguage() {
const value = window.localStorage.getItem("user-Locales") || ""
const result = Translation.isSupportedLocales(value)
if (result) {
return value
} else {
return null
}
},
// 获取当前默认语言
getCurrentDefaultLanguage() {
// 先从缓存获取
const storageLanguage = Translation.getUserLocalStorageLanguage()
if (storageLanguage) {
return storageLanguage
}
// 从浏览器获取,判断用户点脑返回的语言是否带地区,如果有并且支持就返回。否则返回不带地区的
const browserLanguage = Translation.getUserBrowserDefauleLanguage()
if (Translation.isSupportedLocales(browserLanguage.locale)) {
return browserLanguage.locale
}
if (Translation.isSupportedLocales(browserLanguage.localeNoRegion)) {
return browserLanguage.localeNoRegion
}
// 从ENV中获取
return Translation.getEnvDefaultLocales
},
switchLanguage(newValue) {
// 设置当前语言
Translation.currentLanguage = newValue
// 将html标签的lang属性设置为新的语言,因为我的中文字体和英文字体大小不一样,所以使用的css变量
document.documentElement.lang = newValue
if (newValue === "en-US") {
document.documentElement.classList.add("enStyle")
}
// 将当前语言保存到localStorage中
window.localStorage.setItem('user-Locales', newValue)
}
}
export default Translation
一、准备
- 创建文件夹、文件
- 在
i18n/index.js
中创建i18n实例 - 在项目的
main.js
中引入
src/i18n/index.js
import { createI18n } from 'vue-i18n'
import zhCN from "./locales/zh-CN.json"
import enUS from "./locales/en-US.json"
import numberFormats from './rules/number'
import datetimeFormats from './rules/datetime'
export default createI18n({
locale: import.meta.env.VITE_DEFAULT_LOCALE,
fallbackFormat: import.meta.env.VITE_FALLBACK_LOCALE,
legacy: false, // 将legacy设置为false,表示可以使用组合式API
messages: {
'zh-CN': zhCN,
'en-US': enUS,
},
globalInjection: true,
numberFormats,
datetimeFormats
})
src/main.js
import i18n from "./i18n"
import Translation from "./i18n/translation"
// 这里我做的比较简单,直接main中切换当前语言
Translation.switchLanguage(Translation.getCurrentDefaultLanguage());
app.use(i18n);
二、语言切换组件
<div class="language">
<el-popover popper-class="language-popper" placement="bottom" :width="200" trigger="hover">
<template #reference>
<svg t="1717123412401" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9448" width="26" height="26"><path d="..." p-id="9449" fill="#707070"></path></svg>
</template>
<template #default>
<div class="language-box">
<template v-for="(value, key) in LANGUAGES" :key="key">
<div class="item" @click="handleLanguageToggle(key)">{{value}}</div>
</template>
</div>
</template>
</el-popover>
</div>
<script setup>
import { useI18n } from "vue-i18n";
import { LANGUAGES } from "@/i18n/constants.js";
import Translation from "@/i18n/translation";
const { locale } = useI18n();
// 语言切换
function handleLanguageToggle(value) {
locale.value = value // 计算属性
Translation.switchLanguage(value);
router.go(0); // 切换后刷新页面
}
</script>
三、页面使用
方式一:普通 $t("common.querySearch")
方式二:传参 $t('common.queryInputPlhd', {name: $t('common.querySearch')})
方式三:时间 $d(new Date(), "shortFormat")
方式四:setup中使用
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
t("buyBulletin.queryTitle")
<el-form-item :label="$t('buyBulletin.queryTitle')" prop="bulletinTitle">
<el-input
v-model="queryParams.title"
:placeholder="$t('common.queryInputPlhd', {name: $t('buyBulletin.queryTitle')})"
clearable
style="width: 200px"
@keyup.enter="handleQuery" />
</el-form-item>
效果
中文
英文
四、element-plus国际化
<el-config-provider :locale="locale">
<router-view />
</el-config-provider>
<script setup>
import Translation from "@/i18n/translation.js";
import { ElConfigProvider } from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import En from 'element-plus/es/locale/lang/en'
const locale = computed(() => {
const lang = Translation.getCurrentDefaultLanguage()
return lang === 'zh-CN' ? zhCn : En
});
</script>