老闆說咱們的項目要和國際接軌,因而乎,加上了多語言(vue-i18n)。項目用到的UI框架是element ui ,後續echarts、joint等全都得加上多語言。vue
1、言歸正傳,i18n在vue項目裏如何使用呢?git
第一步,Hold On!不對啊,確定是先install啊,不install怎麼use?急得我都和國際接軌了!!!github
npm install vue-i18n -save
看到這段話得時候相信you and me 已經把它install好了,如今,してください....額,有點太接軌了吧!日語都出來了,咳咳,如今,咱們是否是得在main.js裏邊引入vue-i18n呢,而後在目錄下創建language文件夾了呢!!!vue-router
import VueI18n from "vue-i18n";
客官且慢,先別急着動你的small 手手哦!在什麼目錄下創建語言包的文件夾呢?難道要在main.js下?npm
想了想以爲不對。仍是在utils文件夾下,創建一個locales文件夾,最後在main.js裏邊引入。element-ui
第二步,隨便你在哪裏創建一個locales文件夾,在locales下創建index.js、en.json(English)、和zh.json(中文)三個文件。json
不要問我en.json以及zh.json是用來幹嗎的,問就是用來存放語言的!echarts
咱們以 ‘你好帥’ 做爲多語言的案例,注意,兩個文件裏邊key必定要是同樣的。框架
en.json 文件:svg
{ "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
高階:
<i18n></i18n>
:組件塊的拼接與複用
2、到這裏還沒結束呢, 要怎麼結合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呢!!!
3、怎麼結合vue-router呢?
看到這個問題以後,你確定會有疑問!以前不是已經配置好了嗎,一個路由,不寫個$t('xxx')就OK了?這還能難道聰明的我???跟下圖同樣:
router.js文件
// ×××錯誤寫法
export const constantRouterMap = [ {
path: '/home',
name: this.$t('home')
component: () => import('@/views/home/index),
hidden: true
} ]
若是以爲本身成竹在胸,請你把代碼按照這個寫法寫,不出錯要什麼我都不給你!!!哈哈哈!
對的,確定報錯的,vue-i18n和vue-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
到這就結束了!!!新的一天,也請繼續加油吧!!!