Vue2项目中前端国际化处理 vue-i18n + element

4,802 阅读2分钟

这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战

确定需求

下拉菜单选择语言,页面自动切换语言,element默认文字也跟随变化。

中文 image.png English image.png

功能实现

一. 版本选择

  1. vue2 (cn.vuejs.org/v2/guide/in…)
  2. vue-i18n@8 (kazupon.github.io/vue-i18n/in…)
  3. element (element.eleme.cn/#/zh-CN/com…)

vue2 注意选择版本 vue-i18n@8

二. 项目创建

1. src目录下新建 locales 文件夹,并新增需要的 en.json cn.json 语言文档

我们根据项目需要,新增多种语言的json档案,用来分别存储语言值,我创建了中文cn.json和英文en.json
image.png

输入我们需要用到的多语言的值

cn.json
{
  "hello": "你好",
  "table": {
    "date": "日期",
    "name": "姓名",
    "address": "地址"
  }
}
en.json
{
  "hello": "hello",
  "table": {
    "date": "Date",
    "name": "Name",
    "address": "Address"
  }
}

这样做的好处是:之后新增别的语言,只需要复制其中一份json文档保持结构不变修改里面的值即可。

2. 将创建的多语系json文档内容取出并输出成vue-i18n套件需要的数据结构;

新建i18n.js文件

import Vue from "vue";
import VueI18n from "vue-i18n";

//element 国际化处理
import locale from "element-ui/lib/locale";
import elEn from "element-ui/lib/locale/lang/en";
import elCn from "element-ui/lib/locale/lang/zh-CN";

Vue.use(VueI18n);

//将刚刚locales创建的文件分别引入并输出成i18n需要的格式
function loadLocaleMessages() {
  //检测locales文件夹中有多少个语系
  const locales = require.context(
    "./locales",
    true,
    /.json$/
  );
  const messages = {};
  locales.keys().forEach(file => {
    const keyArr = file.split('/');
    keyArr.shift();
    messages[keyArr.join('.').replace(/\.json$/g, '')] = locales(file);
  });
  return {
    cn: { ...messages.cn, ...elCn },
    en: { ...messages.en, ...elEn },
  };
}
const i18n = new VueI18n({
  locale: "cn" ,
  messages: loadLocaleMessages()
});
locale.i18n((key, value) => i18n.t(key, value));

export default i18n;

这一步的重点在于:如何将locales中的json档案内容取出并自生成我们需要的数据
思路:根据json文档名判断语言的种类和个数,并对应取出文件内容,存入messages对象中 这里用到webpack的 require.context(directory,useSubdirectories,regExp) 方法可以获取json文档的内容并引入;

const locales = require.context(
    "./locales",
    true,
    /.json$/
);

创建 const messages = {} 对象 , 用来放入获取到的json数据;

调用locales返回值的key()方法我们可以遍历得到所有的文件路径:打印出来是 ./cn.json ./en.json

这不是我们想要的key值,所以我们需要对文件名做一些字符串的截取处理 cn en

const messages = {};
locales.keys().forEach(file => {
    const keyArr = file.split('/');
    keyArr.shift();
    messages[keyArr.join('.').replace(/\.json$/g, '')] = locales(file);
});
//最后得到
messages:{cn:{...},en:{...}}

最后创建 new VueI18n 实例并导出;

3. element 兼容 Vue-i18n国际化方案

这是按官网给的示例element.eleme.cn/#/zh-CN/com…

image.png

这个操作可以让element组件有一些默认表单的placeholder文字和其他默认文字,会随着语言的切换而变化;

image.png

image.png

4. 将 i18n.js 引入 main.js

引入 Element 和 i18n 文件 并挂载

import Vue from 'vue'
import App from './App.vue'
import i18n from "@/i18n";
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
Vue.config.productionTip = false;

new Vue({
  i18n,
  render: h => h(App)
}).$mount("#app");

5. 使用

格式是 $t("hello")$t('table.date');

<h2>{{ $t("hello") }}</h2>
<el-table
  border
  :data="[]"
  style="width: 100%">
  <el-table-column
    prop="date"
    :label="$t('table.date')"
    width="180"
  >
  </el-table-column>
  <el-table-column
    prop="name"
    :label="$t('table.name')"
    width="180"
  >
  </el-table-column>
  <el-table-column
    prop="address"
    :label="$t('table.address')"
  >
  </el-table-column>
</el-table>

6. 语言切换模块

image.png

使用element的 el-dropdown 组件

app.vue
<template>
  <div id="app">
    <div style="text-align: center">
      <el-dropdown trigger="click" @command="changeLanguage">
        <span class="el-dropdown-link">
          {{ language.title }}<i class="el-icon-arrow-down el-icon--right"></i>
        </span>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item v-for="(item,index) in languageList" :key="index" :command="index" >
            {{ item.title }}
          </el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
    </div>
  </div>
</template>

<script>

export default {
  name: 'App',
  data() {
    return {
      language: {
        value: "ZH-CN",
        title: "简体中文"
      },
      languageList: [
        {
          value: "ZH-CN",
          title: "简体中文"
        },
        {
          value: "EN-US",
          title: "English"
        }
      ]
    }
  },
  methods: {
    changeLanguage(index){
      this.language = this.languageList[index];
      switch (this.language.value) {
        case "ZH-TW":
          this.$i18n.locale = "tw";
          break;
        case "EN-US":
          this.$i18n.locale = "en";
          break;
        case "ZH-CN":
          this.$i18n.locale = "cn";
          break;
      }
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
  margin-top: 20px;
}
</style>

@command会在每次点击下拉子菜单的时候触发changeLanguage() 方法;
在每次语言切换的时候重新设置 this.$i18n.locale;this.language, 就可以实现实时切换语言和展示当前语言的功能了;

三. 结语

OK,以上就是我个人在项目中使用的前端国际化的方案的总结,希望可以给大家带来一点点帮助。

这是我第一次在掘金发文,希望大家多提意见。Thanks♪(・ω・)ノ!!!!!!!!!!