vue項目支持多語言(vue-i18n)


引入vue-i18n

vue-i18n 是一個vue插件,主要作用就是讓項目支持國際化多語言。首先我們引入這個插件:

import Vue from 'vue'

import Vue18n from 'vue-i18n'

Vue.use(Vuei18n);

vue插件的使用方法,通過全局方法Vue.use()使用插件。

插件通常會為Vue添加全局功能。插件的范圍沒有限制-一般有下面幾種:添加全局方法或者屬性;添加全局資源;指令/過濾器/過渡等;通過全局mixin方法添加一些組件選項;添加Vue實例方法,通過把它們添加到Vue.prototype上實現。

Vue.js的插件應當有一個公開方法install,通過代碼可以更直觀的看出插件提供的功能:

//1 添加全局方法或者屬性
Vue.myGlobalMethod=function(){}

//2 添加全局資源
Vue.directive('my-directive',{

bind(el,binding,vnode,oldVnode){}

});

//3 注入組件
Vue.mixin({

created(){}

});

//4 添加實例發方法
Vue.prototype.$myMethods=function(methodOptions){}

使用vue-i18n

<div id="app">{{$t("message.hello")}}</div>

import Vue from 'vue'
import VueI18n from 'vue-i18n'
const messages={   en:{message:{hello:'hello world'}},   cn:{message:{hello:'您好世界'}} }; const i18n=new VueI18n({   locale:'en',   messages:messages }); new Vue({i18n}).$mount("#app");

//output

<div id="app">hello world</div>

可以看到,我們再實例化Vue的時候,將i18n當作一個options傳了進去。之后我們就可以在vue的組件里使用i18n了,使用方法主要是兩種:

1 在組件的template中,使用$t()方法

2 在組件的script中,使用this.$i18n.$t()

添加locales文件夾

messages是一個包含了多語言的對象,它就像哦我們的字典。可以新建一個locales文件夾,存放作於跟我們語言相關的代碼。目前包含三個文件:index.js en.js cn.js

en.js 和cn.js是我們的語言包,是一個json形式。

index.js

import Vue form 'vue'
import VueI18n from 'vue-i18n'
import EN from './en.js'
import CN from './cn.js'
const DEFAULT_LANG='cn'; const LOCALE_KEY='localeLanguage'; const locales={   en:EN,   cn:CN }; const i18n=new VueI18n({   locale:DEFAULT_LANG,   messages:locales });
export const setup
=(lang)=>{   if(lang==undefiend){     lang=window.getStorage(LOCALE_KEY)     if(locales[lang]==undefined){lang=DEFAULT_LANG}   }   window.localstorage.setItem(LOCALE_KEY,lang);   Object.keys(locales).forEach(function(lang){   document.body.classList.remove(`lang-${lang}`);   });   document.body.classList.add(`lang-${lang}`);   document.body.setAttribute('lang',lang);   i18n.locale=lange;   Vue.config.lang=lang;  } setup(); export default I18n;

我們對外提供一個setup的方法,給使用者修改當前使用語種的能力。同時,我們在setup里還做了三件事:

將當前語種存在localStorage中,保存用戶的使用習慣;給body添加語種相關的class,因為不同語言可能導致排版出現差異,我們還需要配置,將當前語種存在

Vue的全局配置中,以便未來可能的使用。

最后在main.js中引入這個index.js就可以了

import Vue from ‘vue’
import App from './app.vue'
import router from './router'
import store from './store'
...
import i18n from '@/locales'

new Vue({router,store,i18n,render:h=>h(App)}).$mount('#app');

vue實例外的js代碼中的額文本怎么替換?
vue實例中我們可以使用this.$i18n.t,這里的this是vue的實例,那項目中的很多js代碼在vue的實例之外。最簡單的方法就是咋需要

使用的地方手動直接import i18n

這樣在vue實例中使用this.$i18n.t,如果不是就先import ,使用i18n.t,這樣顯然復雜了。

為了解決這個問題,最直接的辦法就是把i18n直接掛載在window下,變成全局變量。我們就不需要import了,直接使用i18n.t就可以了;

在main.js:

import Vue from 'vue'

import App from './app.vue'
import store from './store'
import router from './router'
...
import i18n from '@crm/locales'
...

window.i18n = i18n

new Vue({
  i18n,
  router,
  store,
  render: h => h(App),
}).$mount('#app')

然而我們將組件中的import i18n全去掉,並將this.$i18n.t改成i18n.t.項目跑起來之后就報錯了:i18n is not defined

顯然是組件在調用i18n的時候,i18n還沒有掛載到window上,所以執行順序出了問題:

//假設webpack的入口文件是```main.js```
 
//main.js
import moduleA from 'moduleA'
console.log(1)
 
import moduleB from 'moduleB'
console.log(2)
 
//moduleA.js
console.log(3)
 
//moduleB.js
console.log(4)
 
//最終在瀏覽器中打印出的數字順序是: 
3
4
1
2

跟ES6 module的機制有關系。import命令具有提升效果,會提升到整個模塊的頭部,首先執行,這種行為的本質是,import命令是編譯階段執行的,在代碼運行之前。

這樣我們就找到之前報錯的原因了,我們先import app router這些視圖,然后import i18n並掛載在window,所有組件的script中的代碼都先執行,而此時i18n掛載到

window的代碼還沒有執行。import中的script代碼執行完之后才到main.js中其他的js代碼,我們首先將window.i18n=i18n移到locales/index中,然后調整main.js中的import的順序:

//locales/index
...
setup()
window.i18n = i18n

export default i18n

//main.js
import Vue from 'vue'

import i18n from '@crm/locales'
import App from './app.vue'
import store from './store'
import router from './router'
...

 

 

參考:https://segmentfault.com/a/1190000015008808

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM