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

2019-11-12  本文已影响0人  Vampire丶_L

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

上一篇下一篇

猜你喜欢

热点阅读