Vue自定义的组件使用国际化

767 阅读1分钟

最近公司想给项目加上国际化,遇到一个比较棘手的问题。

由于项目引入很多自己的npm包,所以就有一个问题,怎么去解决这些npm包的国际化呢。

  1. 项目配置好语言文件与语言包,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");
    
  2. 这个时候我们运行,就能见到(找不到_t这个方法)

点开里面的源码查看,我们能看到$t是挂在我们Vue的原型上面,**我们每次在调用$t的时候实际上是在调用this.$i18n对象上的\_t方法**  
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b8ac85c08e164f61beb9ececa09f93e6~tplv-k3u1fbpfcp-watermark.image?)  

![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0bd0181c15044d19ac304a0d34447a0b~tplv-k3u1fbpfcp-watermark.image?)  

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

![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/97969b61f7ed4b9c9128eaa4a8438cab~tplv-k3u1fbpfcp-watermark.image?)  

  
**这个 this.options就很好理解了,就是我们 new Vue 实例化的时候提供的对象。**  
  

3. 所以看到这里的话,原因就知道了。我们除了项目自己的new Vue,还有这些npm包自己的Vue实例,(但是这个npm包没有自己的i18n)所以我们只需要重新给我们Vue原型上添加一下。就OK了。

// main.js
Vue.prototype._i18n = i18n;