需求描述:需要中英韩三种语言切换功能,第三方翻译工具有局限,1)翻译不准确,2)调用第三方接口有字数限,所以,最终决定翻译页面中静态文字,接口返回数据不翻译;
实现方案:elementUI提供的国际化多语言。翻译内容分俩部分:1)页面中自定义内容变量;2)elementUI自带插件(日历、表格翻页等)
效果展示
具体实现
npm install vue-i18n
|--src
|------i18n
|----------index.js (注册语言)
|----------langs(文件夹各类语言文件)
|----------------en.js (英文)
|----------------zh-CN.js (中文)
|----------------ko.js (韩文)
2.1、langs中各语言文件数据结构举例
//en.js
const en = {
//路由
route: {
home: 'home',
map: 'Map monitoring',
emissions: 'Emission list',
realData: '',
historyData:"historical data",
dataQuery:"Data query",
loseData:"Lost data",
overData:"Over standard data",
dataReport:"Data report",
ndReport:"Concentration Report",
dischargeReport:"Emission statement",
carReport:"Single vehicle emission statement",
alarmMng:"Alarm management",
statistics:"statistical analysis",
compliance:"Analysis of compliance",
runTarget:"Operation index analysis",
pollutionTax:"Emission tax accounting",
},
footer:{
language: {
zh: 'zh-CN',
en: 'en',
ko: 'ko',
zhName: 'Chinese',
enName: 'English',
koName: 'Korean',
}
}
}
export default en
//ko.js
const ko = {
route: {
home: '집.',
map: '지도 모니터링',
emissions: '배출 명세서',
realData: '실시간 데이터',
historyData:"역사 데이터",
dataQuery:"데이터 조회",
loseData:"손실된 데이터",
overData:"초표준 데이터",
dataReport:"데이터 보고서",
ndReport:"농도 보고서",
dischargeReport:"배출 성명",
carReport:"일차 배출량 보고서",
alarmMng:"경보 관리",
statistics:"통계 분석",
compliance:"표준 상황 분석",
runTarget:"작동 색인 분석",
pollutionTax:"하수 세금 회계"
},
footer:{
language: {
zh: 'zh-CN',
en: 'en',
ko: 'ko',
zhName: '중국 사람',
enName: '영어.',
koName: '한국 사람',
}
}
}
export default ko
2.2、index.js代码,包括自定义页面内容和elementUI插件进行语言切换配置
import Vue from 'vue'
import locale from 'element-ui/lib/locale';
import VueI18n from 'vue-i18n';
//页面中自定义变量
import zh from './langs/zh-CN';
import en from './langs/en';
import ko from './langs/ko';
//element-ui自带多语言配置
import zhLocale from 'element-ui/lib/locale/lang/zh-CN';
import enLocale from 'element-ui/lib/locale/lang/en';
import koLocale from 'element-ui/lib/locale/lang/ko';
Vue.use(VueI18n)
const messages = {
en: {
...en,
...enLocale
},
zh: {
...zh,
...zhLocale
},
ko:{
...ko,
...koLocale
}
}
const i18n = new VueI18n({
locale: localStorage.getItem('changeLang') || 'zh-CN',//从localStorage中拿到用户的语言选择,如果没有,那默认中文。
messages,
silentTranslationWarn: true,
})
locale.i18n((key, value) => i18n.t(key, value)) //为了实现element插件的多语言切换
export default i18n
//引入多语言注册文件
import i18n from '@/i18n/index';
new Vue({
el: '#app',
router,
store,
i18n,//引入i18n
components: { App },
template: ' '
})
{{$t('footer.switchLanguage')}}
{{$t('footer.language.zhName')}}
{{$t('footer.language.enName')}}
{{$t('footer.language.koName')}}
handleSetLanguage方法,切换语言时同步更新store中存储当前语言
handleSetLanguage(lang) {
this.$i18n.locale = lang;
this.$store.commit("setLanguage", lang);
},
const state = {
language: localStorage.getItem('changeLang') ? localStorage.getItem('changeLang') : 'zh-CN',
}
const mutations = {
// 同步操作直接修改state里面的数据
setLanguage: (state, data) => {
state.language = data;
localStorage.setItem('changeLang', data);
},
}
export default {
state,
mutations
}
1)在语言文件中(en.js/ko.js/zh-CN.js)定义复杂数据接口,嵌套层级多,会导致切换时,使用复杂数据页面不会更新,所以我们在切换语言时,在app.vue中使用key,让页面重新渲染一下;
2)我们也可以直接在切换方法中 location.reload(); 页面是整体刷新,用户体验不是很好,建议使用加key重渲染方式;
7.1、标签属性使用
7.2、标签元素中使用
{{$t('public.cancel')}}
7.3、return中使用
return {
iconList: [
{ name: this.$t('dialog.changePwd'), iconName: "icon-psw", dialogFlag: "fixPswFlag" },
{ name: this.$t('dialog.help'), iconName: "icon-help", dialogFlag: "helpFlag" },
{ name: this.$t('dialog.about'), iconName: "icon-about", dialogFlag: "aboutFlag" },
{ name: this.$t('dialog.update'), iconName: "icon-gengxin", dialogFlag: "upFlag" },
{ name: this.$t('dialog.quit'), iconName: "icon-exit", dialogFlag: "exitFlag" },
],
};
7.4、js方法中使用
notify(){
this.$notify.warning({
title: this.$t('msg.warning'),
message: this.$t('msg.exportNodata')
});
}
7.5、自定义校验中使用
var validateCopyPass = (rule, value, callback) => {
var newPasswordFirst = this.form.newPassword;
if (value === '') {
callback(new Error(this.$t('dialog.inputNewAgain')));
} else if (newPasswordFirst != '' && newPasswordFirst != null && value != newPasswordFirst) {
callback(new Error(this.$t('dialog.inputPwdDiff')));
} else {
callback()
}
};