十分鐘入門前端最佳的語言國際化方案

首先,我們先來介紹一下右锨,什么是語言國際化辫封。i18n(其來源是英文單詞 internationalization的首末字符i和n厉熟,18為中間的字符數(shù))是“國際化”的簡稱息拜。在資訊領(lǐng)域溉潭,國際化(i18n)指讓網(wǎng)站無需做大的改變就能夠適應(yīng)不同的語言和地區(qū)的需要。對程序來說该溯,在不修改內(nèi)部代碼的情況下岛抄,能根據(jù)不同語言及地區(qū)顯示相應(yīng)的界面。簡單來說狈茉,就是你的網(wǎng)站可以有多種語言夫椭。

在項(xiàng)目有語言國際化需求的時(shí)候,我們通常會(huì)選擇相應(yīng)的庫氯庆,比如使用Vue框架時(shí)蹭秋,我們會(huì)選擇vue-i18n,當(dāng)我們使react時(shí),我們也許會(huì)使用react-int等堤撵,但在具體實(shí)踐中仁讨,往往只是會(huì)用這個(gè)庫還不行,你還得解決如何同步UI框架的組件語言國際化实昨,以及如何處理從瀏覽器獲取默認(rèn)語言同步問題洞豁。總的來說,要充分考慮到這三個(gè)環(huán)境的語言問題丈挟。

現(xiàn)在我就以在Vue項(xiàng)目下刁卜,使用vue-i18n整個(gè)框架,并且同步更改UI框架Vuetify的組件語言國際化來作為例子曙咽,一步一步實(shí)現(xiàn)整個(gè)項(xiàng)目的語言國際化蛔趴。

安裝

npm

npm install --save vue-i18n@next

yarn

yarn add vue-i18n@next

1.1 定義好語言模版

安裝好這個(gè)庫之后,我們可以先在src目錄下新建一個(gè)i18n文件夾例朱,然后在messages文件夾下面定義好語言模版(名稱沒有硬性要求孝情,后面會(huì)說到命名方案),如圖所示:

1.2 然后洒嗤,將Vue-i18n引入到Vue項(xiàng)目中

importVuefrom'vue'importVueI18nfrom'vue-i18n'importStorefrom'@/store'importmessagesfrom'./messages/en'//默認(rèn)語言 Vue.use(VueI18n)newVue({? router,? i18n,? vuetify,? store,render:(h) =>h(App)}).$mount('#app')

這樣注入到Vue對象中箫荡,我們就可以這樣更改語言了,通過

i18n.locale=lang 去更改你需要的語言烁竭,就可以自動(dòng)獲取相應(yīng)的語言了菲茬,在模版中使用$t('hello')來翻譯。

vue-i18n更多使用姿勢看這里:http://kazupon.github.io/vuei18n/introduction.html#sponsors

我就不過多講解了派撕,我主要說一下與UI框架的同步婉弹、異步加載和默認(rèn)語言處理問題。

這里為了更好的性能终吼,默認(rèn)只加載一種語言镀赌,因?yàn)楫?dāng)語言過多時(shí),全部加載存在性能問題际跪,所以采取了異步加載語言模版的方案商佛。

在i18n文件下,新建index.ts入口文件姆打。

異步加載代碼如下:

/**

* @functin setLang - 設(shè)置應(yīng)用語言

* @param {string} lang - 要設(shè)置語言的名稱

* @return {string} lang - 語言名稱

*/function_set(lang: string):string{? i18n.locale = lang// i18n.fallbackLocale = langAxios.defaults.headers.common['Accept-Language'] = lang? Store.__s('app.language', lang)returnlang}/**

* @functin loadLangAsync - 異步加載語言模版

* @param {string} lang - 需要加載的語言名稱

* @return {string} lang - 加載好的語言名稱

*/exportfunctionsetLang(lang: string):Promise{if(__LOCALE__ !== __LANGS__) {// ___LOCALE__? 是本地已經(jīng)加載好的語言模版數(shù)組if(!__LANGS__.includes(lang)) {// 本地沒有良姆,則加載returnimport(/* webpackChunkName: "lang-[request]" */`@/i18n/messages/${lang}`).then(msgs=>{? ? ? ? i18n.setLocaleMessage(lang, msgs.default[lang])? ? ? ? __LANGS__.push(lang)return_set(lang)? ? ? })? ? }returnPromise.resolve(_set(lang))? }returnPromise.resolve(lang)}

1.3 持久化和默認(rèn)語言問題

const__LANGS__ = ['enUS']// 默認(rèn)語言let__LOCALE__ = Store.state.app.language// 獲取本地存儲(chǔ)的語言// 首次加載沒有存儲(chǔ)的語言,則默認(rèn)使用瀏覽器的語言if(!__LOCALE__) {? __LOCALE__ =window.navigator.language.split('-').join('')? Store.commit('SETLANG', __LOCALE__)}

設(shè)置好語言應(yīng)該添加到vuex的store里面幔戏,并且同步到localstorage玛追,做好語言持久化處理。

這時(shí)候闲延,異步加載和默認(rèn)語言處理問題已經(jīng)解決好了痊剖,現(xiàn)在我們再來說同步Vuetify組件國際化問題。

1.4 同步UI組件國際化

不同UI框架都有自己的組件國際化API垒玲,vuetify提供的是

this.$vuetify.lang.current = lang

因此陆馁,我們只要調(diào)用vue-i18n的setLang方法時(shí),同步調(diào)用這個(gè)方法就好了合愈。

lang() {? ? ? setLang(this.d_language)this.setVuetifyLang(this.d_language) }

這時(shí)叮贩,又有一個(gè)命名的問題击狮,我們的vue-i18n這個(gè)插件可以自己命名語言模版名,但是vuetify的語言名已經(jīng)命名好了妇汗,無法更改的帘不,如下:

因此,這里需要我們的模版名稱應(yīng)該和這里的命名一致杨箭,如簡體中文的模版名應(yīng)該為zhHans,但是我們默認(rèn)語言處理是以瀏覽器的語言來處理的储狭,瀏覽器的語言名使用SO 639-1標(biāo)準(zhǔn) 為各種語言定義了縮略詞互婿,就是以一種簡稱代替某種語言,如英文用en辽狈,中文用zh慈参,部分列表如下:

因?yàn)槊Q不一致,為了統(tǒng)一命名刮萌,我們還應(yīng)該添加一個(gè)翻譯表驮配,以瀏覽器的語言為標(biāo)準(zhǔn),建立語言模版名着茸,并且將與vutify組件不一致的名稱翻譯過來壮锻,如瀏覽器的enUS對應(yīng)vuetify的en,部分翻譯如下:

/**

*? 使 I18n and vuetify 保持一致

*/exportconstTranslateTable: TranslateItem = {enUS:'en',zhCN:'zhHans',zhTW:'zhHant',ja:'ja',ko:'ko'}

當(dāng)然涮阔,vuetify的模版語言可以使可以按需加載的

/**

* the vuetify-i18n language list

* see more :? https://vuetifyjs.com/en/customization/internationalization/

*/constlocalList = ['zhHans','en','ko','zhHant','ja']//加載自己需要的語言// webpack的api猜绣,自動(dòng)模塊化加載constfiles =require.context('vuetify/lib/locale/',true, /\.js$/)constlocales:Array = []files.keys().forEach(key=>{constlanguageName = key? ? .replace('./','')? ? .replace('.js','')? ? .replace('-','')if(localList.includes(languageName)) {? ? locales.push({ [languageName]: files(key).default })? }})

Tips:這里有個(gè)小技巧,當(dāng)默認(rèn)語言為英語時(shí)敬特,我們可以在默認(rèn)不添加翻譯掰邢,如this.$t("hello"),當(dāng)沒有對應(yīng)翻譯時(shí)伟阔,會(huì)翻譯成hello辣之,這樣是不是很方便呢?

所以我的項(xiàng)目中皱炉,都是以英文作為翻譯的key怀估,就不用添加英文的翻譯了,懶人必備娃承。

至此奏夫,我們就完成所有的語言國際化工作了,是不是很簡單呢历筝?

趕快Get吧酗昼,10分鐘就可以輕松入門。

完整的封裝如下:

/**

* vue-i18n

* see more : https://kazupon.github.io/vue-i18n/zh/guide/lazy-loading.html

*/importVuefrom'vue'importVueI18nfrom'vue-i18n'importAxiosfrom'axios'importStorefrom'@/store'importmessagesfrom'./messages/en'Vue.use(VueI18n)const__LANGS__ = ['enUS']let__LOCALE__ = Store.__s('app.language')if(!__LOCALE__) {? __LOCALE__ =window.navigator.language.split('-').join('')? Store.__s('app.language', __LOCALE__)}consti18n =newVueI18n({locale: __LOCALE__,fallbackLocale:'enUS',silentTranslationWarn:false,? messages})/**

* @functin setLang - set the app's language

* @param {string} lang - the language will be setted

* @return {string} lang - langguage name

*/function_set(lang: string):string{? i18n.locale = lang// i18n.fallbackLocale = langAxios.defaults.headers.common['Accept-Language'] = lang? Store.__s('app.language', lang)returnlang}/**

* @functin loadLangAsync - load language asynchronous

* @param {string} lang - the language will be loading

* @return {string} lang - loaded language name

*/exportfunctionsetLang(lang: string):Promise{if(__LOCALE__ !== __LANGS__) {if(!__LANGS__.includes(lang)) {returnimport(/* webpackChunkName: "lang-[request]" */`@/i18n/messages/${lang}`).then(msgs=>{? ? ? ? i18n.setLocaleMessage(lang, msgs.default[lang])? ? ? ? __LANGS__.push(lang)return_set(lang)? ? ? })? ? }returnPromise.resolve(_set(lang))? }returnPromise.resolve(lang)}setLang(__LOCALE__)// initializationexportdefaulti18n

如果需要源碼的話梳猪,請關(guān)注wx公眾號(hào)「前端攻城之路」麻削,回復(fù)“語言國際化”蒸痹,將自動(dòng)獲取到源碼鏈接。

支持

如果這篇文章對你有幫助或者有啟發(fā)的話呛哟,我想請你關(guān)注我叠荠,讓我們一起在前端攻城路上進(jìn)階。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末扫责,一起剝皮案震驚了整個(gè)濱河市榛鼎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鳖孤,老刑警劉巖者娱,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異苏揣,居然都是意外死亡黄鳍,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門平匈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來框沟,“玉大人,你說我怎么就攤上這事增炭∪淘铮” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵弟跑,是天一觀的道長灾前。 經(jīng)常有香客問我,道長孟辑,這世上最難降的妖魔是什么哎甲? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮饲嗽,結(jié)果婚禮上炭玫,老公的妹妹穿的比我還像新娘。我一直安慰自己貌虾,他們只是感情好吞加,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著尽狠,像睡著了一般衔憨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上袄膏,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天践图,我揣著相機(jī)與錄音,去河邊找鬼沉馆。 笑死码党,一個(gè)胖子當(dāng)著我的面吹牛德崭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播揖盘,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼眉厨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了兽狭?” 一聲冷哼從身側(cè)響起憾股,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎箕慧,沒想到半個(gè)月后荔燎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡销钝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了琐簇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒸健。...
    茶點(diǎn)故事閱讀 39,727評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖婉商,靈堂內(nèi)的尸體忽然破棺而出似忧,到底是詐尸還是另有隱情,我是刑警寧澤丈秩,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布盯捌,位于F島的核電站,受9級(jí)特大地震影響蘑秽,放射性物質(zhì)發(fā)生泄漏饺著。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一肠牲、第九天 我趴在偏房一處隱蔽的房頂上張望幼衰。 院中可真熱鬧,春花似錦缀雳、人聲如沸渡嚣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽识椰。三九已至,卻和暖如春深碱,著一層夾襖步出監(jiān)牢的瞬間腹鹉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工莹痢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留种蘸,地道東北人墓赴。 一個(gè)月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像航瞭,于是被迫代替她去往敵國和親诫硕。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1.安裝vue-i18n 2.main.js中引入 importi18nfrom'./i18n/i18n' 3.掛...
    有一個(gè)程序媛閱讀 4,876評論 2 0
  • 安裝 npm install vue-i18n 基本使用 我假設(shè)你的項(xiàng)目是基于vue-cli創(chuàng)建的刊侯。main.js...
    tiancai啊呆閱讀 1,678評論 0 3
  • 標(biāo)簽:多語言 i18n iplas 背景 應(yīng)泰方要求章办,運(yùn)營系統(tǒng)、網(wǎng)上商城以及移動(dòng)端服務(wù)平臺(tái)等項(xiàng)目都要做國際化滨彻,支持...
    傑仔閱讀 2,578評論 0 2
  • 說明:本文基于element-ui@2.13.0亭饵,源碼詳見element休偶。常見的國際化方案有:ECMAscript...
    videring閱讀 11,229評論 0 1
  • 國際化基礎(chǔ)知識(shí) 國際化與本地化 國際化與本地化,或者說全球化辜羊,其目的是讓你的站點(diǎn)支持多個(gè)國家和區(qū)域踏兜。其中國際化是指...
    jsAllen閱讀 5,907評論 0 3