vue使用element-ui开发的后台管理系统使用中英文切换多语言国际化方案步骤流程
2022-08-03 09:57:03
229
{{single.collect_count}}

公司后台管理系统需要使用多语言版本,本次记录使用i18n实现多语言切换的流程步骤:
1、安装工具包

npm install vue-i18n

2、在项目src目录下新建lang文件夹,目录结构如下:

-lang|----index.js // 脚本文件|----en.js // 我们自己的英文包|----zh.js // 我们自己的中文包

element-ui本身有自己的语言包,我们需要先引入。我这里引入了js-cookie工具包来读写cookie,从cookie中看有没有设置中英文标识,没有,就获取浏览器的语言信息来确定中英文标识。

上面indexjs文件内容:

// lang/index.jsimport Vue from 'vue'import VueI18n from 'vue-i18n'import Cookies from 'js-cookie'import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui langimport elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui langimport enLocale from './en'import zhLocale from './zh'Vue.use(VueI18n)const messages = {en: {...enLocale,...elementEnLocale},zh: {...zhLocale,...elementZhLocale}}export function getLanguage() {const chooseLanguage = Cookies.get('language')if (chooseLanguage) return chooseLanguage// if has not choose languageconst language = (navigator.language || navigator.browserLanguage).toLowerCase()const locales = Object.keys(messages)for (const locale of locales) {if (language.indexOf(locale) > -1) {return locale}}return 'zh'}const i18n = new VueI18n({// set locale// options: en | zh | eslocale: getLanguage(),// set locale messagesmessages})export default i18n

zh.js中文包,我是按页面分的,页面下的标识符对应中英文翻译。到时候在页面中使用标识符就可以了。

// lang/zh.jsexport default {navbar: {dashboard: '首页',logOut: '退出登录',profile: '个人中心',theme: '换肤',size: '布局大小'},login: {title: '系统登录',logIn: '登录',usernameTips: '请输入用户名',passwordTips: '请输入密码',remeberPsd: '记住密码',forgotPsd: '忘记密码?',freeRegister: '免费注册',usernameCheckedTips: '请输入用户名',passwordCheckedTips: '请输入密码',codeCheckedTips: '请输入验证码'}}

对应的en.js英文包

// lang/en.jsexport default {navbar: {dashboard: 'Home',logOut: 'Logout',profile: 'Personal Center',theme: 'Change Theme',size: 'Layout Size'},login: {title: 'xxx',logIn: 'xxx',usernameTips: 'xxx',passwordTips: 'xxx',remeberPsd: 'xxx',forgotPsd: 'xxx?',freeRegister: 'xxx',usernameCheckedTips: 'xxx',passwordCheckedTips: 'xxx',codeCheckedTips: 'xxx'}}

3、在项目的main.js文件中引入多语言国际化

// main.jsimport Vue from 'vue'import App from './App'import store from './store'import router from './router'// 引入element-ui框架import ElementUI from 'element-ui'import 'element-ui/lib/theme-chalk/index.css'Vue.use(ElementUI, {i18n: (key, value) => i18n.t(key, value)})import i18n from './lang' // 语言国际化方案new Vue({el: '#app',router,store,i18n, // 挂载i18nrender: h => h(App)})

element-ui需要按照官方说的配置多语言方案。再引入我们自己的i8n配置, 最好挂载到根vue实例上。

4、(可选)在vuex和cookie中保存选择语言的标识
我的vuex目录文件夹为store

store|---modules|---app.js|---getters.js|---index.js

app.js文件内容为

// store/modules/app.jsimport Cookies from 'js-cookie'import { getLanguage } from '@/lang/index'const state = {language: getLanguage()}const mutations = {SET_LANGUAGE: (state, language) => {state.language = languageCookies.set('language', language)}}const actions = {setLanguage({ commit }, language) {commit('SET_LANGUAGE', language)}}export default {namespaced: true,state,mutations,actions}

getters.js内容为

const getters = {language: state => state.app.language}export default getters

index.js内容

// store/index.jsimport Vue from 'vue'import Vuex from 'vuex'import getters from './getters'import app from './modules/app'Vue.use(Vuex)const store = new Vuex.Store({modules: {app},getters})export default store

一样的,最后在main.js引入store并且挂载到vue根实例。

5、在页面中使用
例如, 我在login.vue文件中使用多语言
原来的是这样的

<div class="login-title"><span>登录</span></div>

替换为

<div class="login-title"><span>{{ $t('login.title') }}</span></div>

$t(' ')来获取i8n,属性上使用需要属性绑定,script中使用需要this.$t(''),加this来获取。
在中英文切换按钮上绑定一个切换中英文的方法

 <div ><span @click="handleSetLanguage('zh')">简体中文</span><span>|</span><span @click="handleSetLanguage('en')">English</span></div>// 中间省略 handleSetLanguage(lang) {this.$i18n.locale = langthis.$store.dispatch('app/setLanguage', lang)this.reload() // fix语言切换后,element-ui弹窗提示文字不能切换,必须强制刷新页面才能解决的bug},

备注:this.reload()是我为了修复element-ui,输入框错误提示文字,不会随着切换语言而自动切换的bug,添加了一个强制刷新当前页面的全局方法,使用了vue的provide/reject方式,有需要的可以自己百度。

6、附加需求,我的请求接口也需要传递中英文切换后的语言代码给后台,返回对应的语言版本的后台数据。
所有我的请求头需要配置多语言支持。
可以在axios请求拦截器中统一设置,其他代码略。

service.interceptors.request.use(config => {// 请求发送前的设置config.headers['lan'] = store.getters.languagereturn config},error => {console.log(error) // for debugreturn Promise.reject(error)})

7、路由菜单导航面包屑的i18n国际化
我的菜单名称是根据路由中的meta中的title字段来显示的,譬如我的路由定义:

// 首页{path: '/',component: Layout,redirect: '/home',children: [{path: 'home',name: 'Home',component: () => import('@/views/home/index'),meta: { title: 'Home', icon: 'home', affix: true }}]},

并且我的导航菜单,有一部分是定义在本地的,有一部分是异步从服务器获取的。
so,需要一个定义一个转换函数:

// 路由与面包屑导航栏国际化工具函数export function generateTitle(title) {const hasKey = this.$te('route.' + title)if (hasKey) {const translatedTitle = this.$t('route.' + title)return translatedTitle}return title}

$te$t一样,是i18n定义的函数,测试参数是否在语言包中定义,返回布尔值。文章末尾参考连接中讲i8n源码的文章有提到这些函数,可以参考。
然后在导航菜单的组件内引入使用:

// menu.vue<template> <span>{{ generateTitle(item.meta.title) }}</span> // 使用函数</template><script>import { generateTitle } from '@/utils/i18n' //引入函数methods: {generateTitle, // 这里需要声明一下。其他函数...}</script> 

最后附上两个参考文字地址:
1、https://blog.csdn.net/DOCALLEN/article/details/78408137

2、https://blog.csdn.net/wxl1555/article/details/85112530

3、vue中如何使用i18n实现国际化:https://segmentfault.com/a/1190000016445415

4、前端国际化之Vue-i18n源码分析,提到了$te等其他i18n全局方法。

回帖
全部回帖({{commentCount}})
{{item.user.nickname}} {{item.user.group_title}} {{item.friend_time}}
{{item.content}}
{{item.comment_content_show ? '取消' : '回复'}} 删除
回帖
{{reply.user.nickname}} {{reply.user.group_title}} {{reply.friend_time}}
{{reply.content}}
{{reply.comment_content_show ? '取消' : '回复'}} 删除
回帖
收起
没有更多啦~
{{commentLoading ? '加载中...' : '查看更多评论'}}