最近公司想给项目加上国际化,遇到一个比较棘手的问题。
由于项目引入很多自己的npm包,所以就有一个问题,怎么去解决这些npm包的国际化呢。
-
项目配置好语言文件与语言包,npm外部组件只需配置提供好语言包(en.js/zh.js)
// 项目的i18n.js import Vue from "vue"; import VueI18n from "vue-i18n"; import messages from "./language"; // 语言包 import * as livePlayer from "外部组件"; // npm组件 // 引入npm的语言包 混入进去项目的语言包 let zhlocale = livePlayer.VueI18n.messages.zh;let enLocale = livePlayer.VueI18n.messages.en;Object.assign(messages.zh, zhlocale);Object.assign(messages.en, enLocale); const i18n = new VueI18n({ locale: localStorage.getItem("language") || DEFAULT_LANG, // 设置语言环境 messages: { zh: messages }}); function setLanguage(lang) { i18n.locale = lang; return lang;} export function loadLanguageAsync(lang) { console.log("加载语言包", lang); // 已经加载过的无需加载 if (i18n.locale === lang && loadedLanguages.includes(lang)) { return Promise.resolve(lang); } if (i18n.locale !== lang && loadedLanguages.includes(lang)) { return Promise.resolve(setLanguage(lang)); } // 如果没有加载过的语言 try { return import(/* webpackChunkName: "lang-[request]" */ `./language/${lang}.js`).then((msg) => { i18n.setLocaleMessage(lang, msg.default); loadedLanguages.push(lang); return setLanguage(lang); }); } catch (e) { console.error(e); }} export default i18n;main.js配置
import i18n, { loadLanguageAsync } from "./i18n";loadLanguageAsync(localStorage.getItem("language") || "zh"); new Vue({ store, i18n, render: (h) => h(PageLoader)}).$mount("#application"); -
这个时候我们运行,就能见到(找不到_t这个方法)
点开里面的源码查看,我们能看到$t是挂在我们Vue的原型上面,**我们每次在调用$t的时候实际上是在调用this.$i18n对象上的\_t方法**


那其实我们就可以去看下$i18这个对象是什么时候定义的,去到install方法可以看到,一开始就被定义在Vue.prototype上。现在需要知道这个\_i18n这个玩意在哪里。
**在看install的时候,就可以注意到有一个mixin注入到组件中,在每个组件创建前,会将options的i18n给this.\_i18n**

**这个 this.options就很好理解了,就是我们 new Vue 实例化的时候提供的对象。**
3. 所以看到这里的话,原因就知道了。我们除了项目自己的new Vue,还有这些npm包自己的Vue实例,(但是这个npm包没有自己的i18n)所以我们只需要重新给我们Vue原型上添加一下。就OK了。
// main.js
Vue.prototype._i18n = i18n;