不要问为啥要使用国际化(vue-i18n),现在很多主流的UI框架,上去你会发现他们的文档都是支持多语言的。那我们在工作中难免会有潜在的客户是来自其他国家的。随着时间的推移可能还会支持更多的语言种类,那程序的设计就很至关重要,不可能说多一个国家的客户,我们就去改一次程序。合理的方案应该是运维或者不懂开发的同事直接通过编辑文件或者数据库数据就能增加一种语言才是最实际的。至于采用存储文件还是数据库。根据自己的需求合理安排就好。
程序我已经搭建好了Vite4+Pinia2+vue-router4+ElmentPlus搭建Vue3项目(组件、图标等按需引入)
这里用到cookie的原因是,比如我们设置的是中文,那么我们后续进入系统默认的就应该是中文。
yarn add vue-i18n js-cookie -S
yarn add @types/js-cookie -D
// @ts-ignore
import Cookies from 'js-cookie'
// key自己随意设置
const languageKey = 'ts_EtcEnd_language'
export const getLanguage = () => Cookies.get(languageKey)
export const setLanguage = (language: string) => Cookies.set(languageKey, language)
我是做了分类,如果全写在一个对象里面,难免会有重复的key。所以分类能够尽量去减少这个问题的出现。rouer代表路由,system代表系统,login代表登录。
export default {
route: {
home: '首页',
home1: '首页1'
},
system: {
title: 'Etc.End的演示案例',
},
login: {
userName: '请输入用户名',
passWord: '请输入密码',
logIn: '登录',
userNameMessage: '请输入正确的用户名',
passWordMessage: '密码长度为6~30'
}
}
export default {
route: {
home: 'Home',
home1: 'Home1',
},
system: {
title: 'Etc.End Demonstrate Case',
},
login: {
userName: 'Please input userName',
passWord: 'Please input password',
logIn: 'Login',
userNameMessage: 'Please enter the correct user name',
passWordMessage: 'The password length is 6 ~ 30'
}
}
// @ts-ignore
import { createI18n } from 'vue-i18n'
import { getLanguage } from '@/utils/cookies'
import enLocale from './en'
import zhLocale from './zh'
const messages = {
en: {
...enLocale
},
'zh-cn': {
...zhLocale
}
}
export const getLocale = () => {
//读取cookie存入的当前语言
const cookieLanguage = getLanguage()
//如果有返回当前语言
if (cookieLanguage) {
return cookieLanguage
}
//如果没有,获取系统语言
const language = navigator.language.toLowerCase()
//获取messages 语言 遍历
const locales = Object.keys(messages)
for (const locale of locales) {
//如果messages 包里面有系统语言返回
if (language.indexOf(locale) > -1) {
return locale
}
}
// 默认语言 简体中文
return 'zh-cn'
}
//注册i8n实例并引入语言文件
const i18n = createI18n({
legacy: false, // 是否启用传统模式,默认true启用,需要在Composition API中使用则设为false
globalInjection: true, // 全局注入,页面内调用全局i18n需要用$t('xxx'),而非t('xxx')
locale: getLocale(), //默认显示的语言
messages //引入语言文件
})
export default i18n;
引入刚刚写好的src/basics/lang/index.ts文件
import { createApp } from 'vue'
import App from './App.vue'
import 'animate.css'
import { createPinia } from 'pinia';
import { registerStore } from '@/pinia';
import router from '@/router';
import '@/router/permission'
import 'element-plus/theme-chalk/dark/css-vars.css'
import "element-plus/theme-chalk/el-message.css";
import "element-plus/theme-chalk/el-message-box.css";
// 国际化
import i18n from '@/basics/lang'
const app = createApp(App);
app.use(i18n)
app.use(router)
app.use(createPinia())
registerStore()
app.mount('#app')
{{ locale }}
{{ $t('system.title') }}
{{ $t('login.logIn') }}
import { defineStore } from 'pinia';
import { getLocale } from "@/basics/lang";
import { setLanguage } from "@/utils/cookies";
interface IAppState {
language: string
}
export const appModule = defineStore({
id: 'app',
state(): IAppState{
return {
language: getLocale(),
}
},
getters:{},
actions:{
setLanguage(language: string) {
this.language = language
setLanguage(language)
},
}
})
增加login路由,因为我是动态路由,没有做的小伙伴自己手动去增加以下login路由就好。Vite4 + Vue3 + vue-router4 动态路由
const list:MenuType[] = [
{
path: '/',
title: 'ts-super-web',
component: 'Layout',
redirect: '/home',
children: [
{
title: 'home',
path: 'home',
component: 'home'
},
{
title: 'home1',
path: 'home1',
component: 'home1'
},
{
title: 'login',
path: 'login',
component: 'login'
}
]
}
]
我是Etc.End。如果文章对你有所帮助,能否帮我点个免费的赞和收藏。