vue-i18n安装、vue文件国际化、纯js文件国际化、语言切换
1、安装
npm install vue-i18n --save
2、创建多语言配置(vue-i18n)相应文件夹
- 在src目录下创建language文件夹(文件夹名可自定义,建议使用language);
|——src
|——|——languege
|——|——|——index.js
|——|——|——en.js
|——|——|——zh.js
- /src/language/index.js内容如下
import Vue from "vue";
import VueI18n from "vue-i18n";
//引入自定义语言配置
import developZh from './zh';
import developEn from './en';
//引入UI框架语言配置---elementui
import locale from 'element-ui/lib/locale';
import enLocale from 'element-ui/lib/locale/lang/en';
import zhLocale from 'element-ui/lib/locale/lang/zh-CN';
Vue.use(VueI18n);
const i18n = new VueI18n({
locale: localStorage.lang || "zh",
messages: {
'zh': {
...developZh,
...zhLocale
}, // 中文语言包
'en': {
...developEn,
...enLocale
} //英文语言包
}
});
locale.i18n((key, value) => i18n.t(key, value))
export default i18n;
- /src/language/zh.js内容如下—(本人习惯按照职责划分,这里的结构可按照自己的习惯来)
/**
* 修改zh.js文件后,应将修改或新增的自动同步到en.js
* zh.js 和 en.js 字段数量应一致,如不熟悉字段使用范围,应尽量新增字段,避免修改现有字段
* **/
export default {
lang: {
action: {
// 动作类
add:"新增",
edit:"编辑"
},
description: {
// 描述类
Welcome:'欢迎您!'
},
message: {
// 返回提示类
},
contentTips: {
// 页面提示信息:
uploadFirst:'请先上传文件!'
}
}
}
- /src/language/en.js内容如下
/**
* 修改enjs文件后,应将修改或新增的自动同步到zh.js
* zh.js 和 en.js 字段数量应一致,如不熟悉字段使用范围,应尽量新增字段,避免修改现有字段
* **/
export default {
lang: {
action: {
// 动作类
add:"add",
edit:"edit"
},
description: {
// 描述类
Welcome:'Welcome',
},
message: {
// 返回提示类
},
contentTips: {
// 页面提示信息:
uploadFirst:'Please upload the import file first'
}
}
}
3、在main.js引入i18n(language文件夹)
import i18n from './language'
new Vue({
el: '#app',
i18n,
router,
store,
render: h => h(App)
})
4、vue页面引用i18n
按照常规模式引用即可
1、dom部分
<span>{{$t("lang.action.add")}}:XXXXXXXX</span>
2、js部分
methods: {
function( val ){
return this.$t('lang.contentTips.uploadFirst');
}
}
5、添加多语言切换功能
- 在vue文件中添加操作功能
<template>
<el-select v-model="language" @change="changeLang" class="changeLangstyle">
<el-option
v-for="item in languageList"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
</template>
<script>
export default {
name: 'CommonHeader',
data(){
return {}
},
created() {
if (this.$i18n.locale == 'en') {
this.language= this.$t('lang.description.ToEnglish')
}else{
this.language= this.$t('lang.description.ToChinese'); }
},
computed: {
languageList: function () {
return [this.$t('lang.description.ToChinese'),this.$t('lang.description.ToEnglish')] }
},
methods: {
changeLang( val ){
let locale = this.$i18n.locale;
if(val==this.$t('lang.description.ToEnglish')){
locale === 'zh' ? this.$i18n.locale = 'en' : this.$i18n.locale = 'zh';
localStorage.lang=this.$i18n.locale;
this.language= this.$t('lang.description.ToEnglish');
}else if(val==this.$t('lang.description.ToChinese')){
locale === 'zh' ? this.$i18n.locale = 'en' : this.$i18n.locale = 'zh';
localStorage.lang=this.$i18n.locale;
this.language= this.$t('lang.description.ToChinese');
}
}
}
}
</script>
6、纯js文件引用i18n
在前后端分离项目中,对于js文件里的文字进行国际化,常规的引用Vue是不可行的
1、第一种方式:在main.js中把Vue对象赋值给一个变量
//main.js中的vue实例赋给变量-----vm
window.vm = new Vue({
el: "#app",
i18n,
router,
store,
template: "<App/>",
components: {App},
ready: function () {
}
});
//js代码中修改如下----- window.vm变量
MessageBox.confirm(
window.vm.$t('authentication.failed.message'),
window.vm.$t('authentication.failed.confirmLogout'),
{
confirmButtonText: window.vm.$t('authentication.failed.reLogin'),
cancelButtonText: window.vm.$t('authentication.failed.cancel'),
type: 'warning'
}
)
2、第一种方式:传递相应的字符串,页面渲染使用----router.js国际化
router中定义前端页面的调用信息,一般左侧导航或者首部导航会直接引用,显示信息因此可通过传递字符串的方式渲染至vue页面
- router.js文件
{
path: "/tools",
name: "tools",
component: Layout,
redirect: "/layout/tools",
children: [
{
path: "/layout/tools",
name: "tools",
component: Tools,
// 'lang.description.tasks'-------语言包中对应位置结构,
meta: {title: 'lang.description.tasks', icon: 'el-icon-tickets'},
},
{
path: "/layout/tools/file",
name: "exportfile",
component: DefaultModel,
// 'lang.action.export'-------语言包中对应位置结构,
meta: {title: 'lang.action.export', icon: 'el-icon-location'},
hidden: true
}
]
- sidebar.vue文件
<template>
<div v-if="!item.hidden">
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
// 此处渲染的路由信息,onlyOneChild.meta.title-----路由变量,取得路由变量中存的字符串
<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="$t(onlyOneChild.meta.title)" />
</el-menu-item>
</app-link>
</template>
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
<template slot="title">
//此处渲染的路由信息,item.meta.title-----路由变量,取得路由变量中存的字符串
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="$t(item.meta.title)" />
</template>
<sidebar-item
v-for="child in item.children"
:key="child.path"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path)"
class="nest-menu"
/>
</el-submenu>
</div>
</template>