Element + Vue I18n動態import加載國際化語言包翻譯文件


需求

項目為多頁應用,包含產品a、b、c、d、e,每個產品都有自己的翻譯文件。
一次加載所有翻譯文件是極度不合理的。於是考慮動態加載。

實現

參考官方文檔:延遲加載翻譯

項目結構

│
├── dist // 靜態資源輸出目錄 │ ├── src │   ├── assets │   ├── components │   ├── lang // 語言翻譯文件 │   ├── a │   ├── en_US.js │   └── zh_CN.js │   ├── b │   ├── en_US.js │   └── zh_CN.js │   ├── c │   ├── en_US.js │   └── zh_CN.js │   ├── d │   ├── en_US.js │   └── zh_CN.js │   ├── e │   ├── en_US.js │   └── zh_CN.js │   ├── pages │   ├── a │   ├── b │   ├── c │   ├── d │   ├── e │   ├── utils │   ├── i18n.js │   ├── ...

i18n.js

import Vue from 'vue' import VueI18n from 'vue-i18n' import ElementLocale from 'element-ui/lib/locale' import enLocale from 'element-ui/lib/locale/lang/en' import zhLocale from 'element-ui/lib/locale/lang/zh-CN' // LANG:全局變量,從cookie中獲取的當前語言版本,'zh_CN'、'en_US' // IS_INTL:全局變量,是否為國際版 import { LANG, IS_INTL } from '@/constant' Vue.use(VueI18n) const i18n = new VueI18n({ silentTranslationWarn: true }) // 這里需要覆蓋Element本地化函數,不然會沖突 ElementLocale.i18n((key, value) => i18n.t(key, value)) export default i18n /** * 更改vueI18n實例 * @param lang 'zh_CN'、'en_US' */ function setI18nLang (lang) { i18n.locale = lang // axios.defaults.headers.common['Accept-Language'] = lang document.querySelector('html').setAttribute('lang', lang) return lang } /** * 動態加載語言 * @param path 當前路徑(對應lang下文件夾名) */ const _LANGS = ['zh_CN', 'en_US'] const ELEMENT_LANG = { zh_CN: zhLocale, en_US: enLocale } let loadedLanguages = [] export function loadLanguageAsync (path) { // lang目前是從cookie中獲取,所以沒有作為參數傳遞,此處lang也可作為變量傳遞 // 如果cookie中沒有獲取到語言項,國際版默認初始化為英文 const lang = LANG || (IS_INTL ? 'en_US' : 'zh_CN') if (!path || !_LANGS.includes(lang)) return if (i18n.locale !== lang) { if (!loadedLanguages.includes(lang)) { // 文件大時可拆分打包,目前項目中翻譯文件均為4、5K左右,就沒拆 // return import(/* webpackChunkName: "lang-[request]" */ `@/lang/${path}/${lang}`).then(msgs => { return import(`@/lang/${path}/${lang}`).then(msgs => { const _temp = Object.assign(msgs.default, ELEMENT_LANG[lang]) i18n.setLocaleMessage(lang, _temp) loadedLanguages.push(lang) return setI18nLang(lang) }) } return Promise.resolve(setI18nLang(lang)) } return Promise.resolve(lang) }

main.js

import Vue from 'vue' import App from './label.vue' import store from './store/index' import router from './router/index' import i18n, { loadLanguageAsync } from '@/utils/i18n' import '@label/plugins/element-ui' import '@/assets/styles/common.less' import AppComponents from '@label/components/index' // 注冊全局組件 Vue.config.productionTip = false Vue.use(AppComponents) // a頁 loadLanguageAsync('a').then(_ => { new Vue({ i18n, store, router, render: h => h(App) }).$mount('#app') })

切換語言組件

主要操作:切換時setCookie后重刷頁面
原因:本來直接調用loadLanguageAsync是可以正常重刷語言包的,但是這里由於頁面某些顯示內容是來源於后端接口的,還是得重新請求,所以重刷了整頁

setCookie('jd.erp.lang', lang || 'en_US', 1, { path: '/', domain: CUR_HOST_SUFFIX }) window.history.go(0)

組件內容如下:

// langs.vue <template> <el-dropdown class="icon-info icon-langs" @command="changeLang" > <img :src="imgSrc"> <el-dropdown-menu slot="dropdown"> <el-dropdown-item v-for="item in langs" :key="item.value" :command="item.value" :disabled="item.value === locale" > {{ item.label }} </el-dropdown-item> </el-dropdown-menu> </el-dropdown> </template> <script> import { LANG, CUR_HOST_SUFFIX } from '@/constant' import { setCookie } from '@/utils/utils' export default { name: 'langs', data () { return { imgSrc: require('@label/assets/icons/header-langs.svg'), locale: LANG, langs: [ { label: '中文', value: 'zh_CN' }, { label: 'English', value: 'en_US' } ] } }, methods: { changeLang (lang) { this.locale = lang setCookie('jd.erp.lang', lang || 'en_US', 1, { path: '/', domain: CUR_HOST_SUFFIX }) window.history.go(0) } } } </script>
 


免責聲明!

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



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