vue实现多语言国际化(vue-i18n),结合element ui、vue-router、echarts以及joint等。

老板说我们的项目要和国际接轨,于是乎,加上了多语言(vue-i18n)。项目用到的UI框架是element ui ,后续echarts、joint等全都得加上多语言。

 

一、言归正传,i18n在vue项目里如何使用呢?

 

第一步,Hold On!不对啊,肯定是先install啊,不install怎么use?急得我都和国际接轨了!!!

npm install vue-i18n -save

看到这段话得时候相信you and me 已经把它install好了,现在,してください....额,有点太接轨了吧!日语都出来了,咳咳,现在,我们是不是得在main.js里边引入vue-i18n呢,然后在目录下建立language文件夹了呢!!!

import VueI18n from "vue-i18n";

客官且慢,先别急着动你的small 手手哦!在什么目录下建立语言包的文件夹呢?难道要在main.js下?

想了想觉得不对。还是在utils文件夹下,建立一个locales文件夹,最后在main.js里边引入。

 

第二步,随便你在哪里建立一个locales文件夹,在locales下建立index.js、en.json(English)、zh.json(中文)三个文件。

不要问我en.json以及zh.json是用来干嘛的,问就是用来存放语言的!

我们以 ‘你好帅’ 作为多语言的案例,注意,两个文件里边key一定要是一样的。

en.json 文件:

{
  "handsome":“ZZC,You're handsome”  
}

zh.json 文件:

{
  "handsome":“ZZC,你好帅”  
}

 

第三步,我们在index.js来写多语言的实现。好,两分钟已经过去了,代码已经写好了!哈哈哈,看下边代码吧,有注释哦~

import Vue from 'vue' // 引入vue实例
import VueI18n from 'vue-i18n' // 引入vue-i18n多语言包

Vue.use(VueI18n) // vue使用vue-i18n

const DEFAULT_LANG = 'en' // 默认语言为英文
const LOCALE_KEY = 'DemoLanguage' // localStorage来存放的key,名字随便定,接下来会用到。

const locales = { // 引入zh.json以及en.json
    zh: require('./zh.json'),
    en: require('./en.json')
}

const i18n = new VueI18n({ // 创建带有选项的 VueI18n 实例
    locale: DEFAULT_LANG, // 语言标识,在这里默认为en,即为英文
    messages : locales // 语言包,上边创建的json文件
})

export const setup = lang => { //切换语言的函数,lang为语言标识,en或者zh
   // 在此判断lang的值,如果未定义,则让lang默认为DEFAULT_LANG,目的是为了让用户在未选择语言的时候默认为英文。
    if(lang == undefined){
        lang = window.localStorage.getItem(LOCALE_KEY)
        if ( locales[lang] == undefined ) {
            lang = DEFAULT_LANG
        }
    }
  // 若lang有值,那么存入localStorage中,key为LOCALE_KEY,value为lang。 window.localStorage.setItem(LOCALE_KEY, lang) Object.keys(locales).forEach(item
=> { document.body.classList.remove('lang-${item}') }) document.body.classList.add('lang-${lang}') document.body.setAttribute('lang', lang) Vue.config.lang = lang i18n.locale = lang } setup() export default i18n

 

第四步,代码写好以后,在main.js注入多语言vue-i18n依赖。

import i18n from '../utils/locale'
// ···
new Vue({
  store,
  router,
  i18n,
  render: h => h(App)
})

 

最后,接着就可以在vue页面中使用了,在这里我们只讲$t的使用。

<template>
  <section>  
    <h3>{{$t("handsome")}}</h3>
    <el-button @click="changeLanguage('en')">English</el-button>
    <el-button @click="changeLanguage('zh')">中文</el-button>
  </section>
</template> ... import { setup } from "../utils/locales"; // methods changeLanguage(lang) {  this.$i18n.locale = lang
  setup(lang);
  location.reload() // 为了重新实例化vue-router对象,避免一些bug
}

扩展,具体请转到https://hachijiang.github.io/vue-i18n%E5%8E%9F%E7%90%86%E8%A7%A3%E6%9E%90/

基本方法:

  • $t:普通词
  • $tc:单复数
  • $te:check 翻译key是否存在
  • $d:时间日期
  • $n:货币数字

自定义指令:v-t

高阶:

  • linked locale messages
  • <i18n></i18n>:组件块的拼接与复用

 

二、到这里还没结束呢, 要怎么结合element ui 呢?

我们都知道,element ui有它自带的一套国际化配置。像日期控件、分页控件等,不会随着vue-i18n的配置改变而改变,换句话说,以上的代码,是不能够切换element ui内部控件的语言类型。

嗯,那么问题来了,怎么在切换语言的时候同时切换element ui 内部的控件呢???

别急,我们还是来到刚才的那段代码中,添加一些神秘的代码,就可以切换了。

好了,20秒已经过去了,代码已经写好了。客官请看粗大...啊呸加粗加大部分

import Vue from 'vue'
import VueI18n from 'vue-i18n'

// 引入element ui自带语言包 import ElementUILocale 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 DEFAULT_LANG = 'en' const LOCALE_KEY = 'DemoLanguage' const locales = { zh: require('./zh.json'), en: require('./en.json') } const i18n = new VueI18n({ locale: DEFAULT_LANG, messages : locales, }) const UIlocales = { zh: zhLocale, en: enLocale }
// 通过判断lang语言标志符来return先对应的语言 const setUIlocales
= lang =>{ switch (lang) { case 'zh': return UIlocales.zh case 'en': return
UIlocales.en } } export const setup = lang => { if(lang == undefined){ lang = window.localStorage.getItem(LOCALE_KEY) if ( locales[lang] == undefined ) { lang = DEFAULT_LANG } } window.localStorage.setItem(LOCALE_KEY, lang) Object.keys(locales).forEach(item => { document.body.classList.remove('lang-${item}') }) document.body.classList.add('lang-${lang}') document.body.setAttribute('lang', lang) Vue.config.lang = lang i18n.locale = lang ElementUILocale.use(setUIlocales(lang)) // element ui 切换语言 } setup() export default i18n

哈哈哈,是不是很简单啊!现在快去试试看切换语言后分页或者时间等其他控件是否有change呢!!!

 

三、怎么结合vue-router呢?

看到这个问题之后,你肯定会有疑问!之前不是已经配置好了吗,一个路由,不写个$t('xxx')就OK了?这还能难道聪明的我???跟下图一样:

router.js文件

// ×××错误写法
export const constantRouterMap = [ {
  path:
'/home',
  name: this.$t('home')
  component: () => import('@/views/home/index),
  hidden: true
} ]

如果觉得自己胸有成竹,请你把代码按照这个写法写,不出错要什么我都不给你!!!哈哈哈!

对的,肯定报错的,vue-i18nvue-router属于同级,你怎么去用呢???

哈哈哈,仔细思考一下,既然$t('key')这种写法不对,那么,我们还能想到什么呢???给你三分钟思考的时间!!!

滴~滴~滴~老司机说三小时都过去了,你想出来了吗???

对!!!这个key才是你要翻译的name,为何纠结于一定用$t('key')这种行不通的法子捏?

既然方法不重要,key重要,那么我们就把$t拿掉,留下key。

export const constantRouterMap = [
  { 
  path: '/home',
  name: 'home'
  component: () => import('@/views/home/index),
  hidden: true 
  }
]

zh.json

{
  "home":"我的主页"  
}

en.json

{
  "home":"My Home"  
}

这样的话,我们只要在渲染的时候把相应的name用$t('name')来切换就可以了。关注加粗的部分就行了!

<div>
  <template v-for="item in routes" v-if="!item.hidden&&item.children">
  <el-submenu v-if="hasChildren(item)" :index="item.name||item.path" :key="item.name">
  <template slot="title">
  <span class="router_border"></span>
  <svg-icon v-if="item.meta&&item.meta.icon" :icon-class="item.meta.icon"></svg-icon>
  <span v-if="item.name" slot="title">{{$t(item.name)}}</span>
  </template>
  </el-submenu>
  </template>
</div

到这就结束了!!!新的一天,也请继续加油吧!!!

 

posted @ 2019-03-19 18:32  我不是橙子啊  阅读(7220)  评论(3编辑  收藏  举报