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

首先,我們先來介紹一下,什么是語言國際化。i18n(其來源是英文單詞 internationalization的首末字符i和n,18為中間的字符數(shù))是“國際化”的簡稱。在資訊領(lǐng)域,國際化(i18n)指讓網(wǎng)站無需做大的改變就能夠適應(yīng)不同的語言和地區(qū)的需要。對(duì)程序來說,在不修改內(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對(duì)象中,我們就可以這樣更改語言了,通過

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

vue-i18n更多使用姿勢(shì)看這里: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)在我們?cè)賮碚f同步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對(duì)應(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)沒有對(duì)應(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

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

支持

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容