美文网首页
Vue-i18n如何应用到vue+Element/iView项目

Vue-i18n如何应用到vue+Element/iView项目

作者: Vampire丶_L | 来源:发表于2019-11-12 11:47 被阅读0次

    Vue-i18n是对vue项目国际化得一种实现(react-i18n同理),当然也可以使用i18next,本文只对Vue-i18n进行讲解。

    一,首先自己学习官方文档
     安装vue-i18n的依赖包,安装完成后,新建i18n.js文件。
    npm install vue-i18n

    二,配置i18n到项目中的步骤
    (1)在i18n.js中引入所需的包如下

    import Vue from 'vue';
    import VueI18n from 'vue-i18n'
    import zhTranslation from './public/locales/zh-CN'; // 中文语言环境
    import enTranslation from './public/locales/en-US'; // 英文语言环境
    import zh from 'element-ui/lib/locale/lang/zh-CN.js'; //element-ui的中文语言环境
    import locale from 'element-ui/lib/locale' // element-ui的语言环境
    import axios from 'axios'
    

    接下来就是使用这些引入的包了,先呢new一个vue-i18n对象,看过文档的应该都会。

    
    const messages = {};
    // 将项目的中文语言环境和element-ui中文环境合并,然后添加到messages里
    messages['zh'] = Object.assign({}, zhTranslation, zh); 
    
    Vue.use(VueI18n);
    
    export const i18n = new VueI18n({
      locale: 'zh', // 设置地区
      messages, // 设置地区信息,
      fallbackLocale: 'zh' // 回退语言环境
    });
    locale.i18n((key, value) => i18n.t(key, value)) // 重点:为了实现element插件的多语言切换
    const loadedLanguages = ['zh']; // 默认安装的语言
    
    

    (2)接下来的要做的事情就是:在切换语言的时候,1.异步加载element-ui的目标语言环境,2.请求项目自身的语言环境,一步步来,代码贴上:

    /**
     * @name: changeElementLang
     * @msg: 异步请求element-ui的语言环境
     * @param {string} lang 目标语言
     * @return: Promise 目标语言环境element-ui的locale
     */
    function changeElementLang(lang) {
      return new Promise((resolve, reject) => {
        const elementLang = () => import(`element-ui/lib/locale/lang/${lang}`); // import属于异步操作
        elementLang().then((langRes) => {
          const eleLang = langRes['default'];
          resolve(eleLang);
        }).catch(() => {
          reject(lang);
        })
      })
    }
    
    
    
    
    /**
     * @name: loadLanguageAsync
     * @param {string} lang 目标切换语言
     * @return: 
     */
    export function loadLanguageAsync(lang) {
      if(i18n.locale !== lang) {
        if(!loadedLanguages.includes(lang)) {
          // 异步请求目标语言环境的loacle
          const languagePromise = new Promise((resolve ,reject) => {
            axios.get(`/api/newsweb/`).then(res => {
              resolve(enTranslation);
            }).catch(() =>{
              reject(lang);
            })
          })
          const elementLanguage = changeElementLang(lang); // 异步请求目标语言环境element-ui的locale
          const arrayLanguage = [languagePromise, elementLanguage]; 
          return Promise.all(arrayLanguage).then((arrayLanguage) => {
            loadedLanguages.push(lang); // 请求成功后进行标记,避免重复请求
            // 将element的locale信息和请求回来的locale合并
            messages[lang] = Object.assign({}, arrayLanguage[0], arrayLanguage[1]); 
            i18n.setLocaleMessage(locale, messages); // 设置语言环境的 locale 信息
            i18n.locale = lang; // 修改语言环境
            setI18nLanguage(lang);
          }).catch(() => {
            console.log('切换失败,语言回滚');
          })
        } else {
          i18n.locale = lang;
          return Promise.resolve(setI18nLanguage(lang));
        }
      } else {
        return Promise.resolve(lang);
      }
    }
    
    

    这个函数有点长,两个if条件判断可以根据变量去判断的逻辑关系,这里只解释异步请求和Promise.all()这两个地方,languagePromise是一个promise对象,异步请求项目的语言环境,这里的url不用在意,因为我用本地的英语语言环境resolve(enTranslation)去代替请求回来的数据,为了方便测试而已。
    Promise.all()不熟悉的同学可以先去了解下(只能传入一个数组或者字符串),这里传入一个数组,数组的元素就是前面两个用promise对象包起来的异步操作,等到这两个异步操作都执行了resolve(),才会执行Promise.all().then(),参数中有一个异步操作执行了reject()Promise.all()就会执行catch()
    等到两个参数都resolve()后,将resolve过来的数据进行合并,然后调用setLocaleMessage()修改语言环境,最后的i18n.locale = lang;才是改变语言的操作。
    最后贴上setI18nLanguage(lang)函数的代码:

    function setI18nLanguage(lang) {
      // 请求头带上语言的字段,告诉后端自己需要的数据语言
      axios.defaults.headers.common['Accept-Language'] = lang;
      document.querySelector('html').setAttribute('lang', lang);
      return lang;
    }
    

    三,测试
     贴上测试代码:

    <template>
        <div>
            {{ $t('language.title') }}
            :
            <button @click="changeLanguage('zh')" :class="{active: isLang('zh')}">
                {{ $t('language.zh') }}
            </button>
            <button @click="changeLanguage('en')" :class="{active: isLang('en')}">
                {{ $t('language.en') }}
            </button>
        </div>
    </template>
    
    <script>
    import { loadLanguageAsync } from '../../i18n'
      export default {
        data() {
          return {};
        },
    
        mounted() {
          this.changeLanguage('zh');
        },
    
        methods: {
          isLang(lng) {
            return this.$i18n.locale === lng;
          },
          changeLanguage(lng) {
            loadLanguageAsync(lng);
            // 切换语言后强制重新渲染,重新请求对应语言的数据
            Promise.resolve().then(_ => {
              this.$forceUpdate();
            })
          },
        },
      };
    </script>
    
    

    项目展示:

    初始加载 切换 切换英文之后红色框部分就是改变的

    别忘了i18n对象要传递给Vue app

    相关文章

      网友评论

          本文标题:Vue-i18n如何应用到vue+Element/iView项目

          本文链接:https://www.haomeiwen.com/subject/asvsvctx.html