vue i18n 国际化

127 阅读1分钟

参考:
juejin.cn/post/708273… juejin.cn/post/706534…

1. 在src目录下新建lang文件夹

image.png

image.png

文件目录根据实际项目来定义
en: 英文语言包,里面可以在定义文件或者是js文件
zh: 中文语言包,
index.js: 整合语言包的js文件,然后在 main.js 中导入 这个js文件,毕竟 main.js 中最后只需要一个 VueI18n 的实例即可!
js文件中的格式:例如:errorPage.js文件:

export default {
    header: {
      title: '头'
    },
    table: {
      title: '标题'count: '序号'
    },
    footer: {
      title: '尾巴'
    }
}

2.整合中英文的index.js文件:

import Vue from 'vue';
import VueI18n from 'vue-i18n';
import Cookies from 'js-cookie';
import elementEnLocale from 'element-ui/lib/locale/lang/en'; // element-ui lang
import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN';// element-ui lang

const enModulesFiles = require.context('./en', true, /.js$/);//引入自定义的语言文件夹
const enModuleObj = {}; const zhModuleObj = {};
const enLocaleModules = enModulesFiles.keys().reduce((modules, modulePath) => {//对en文件夹下的子文件及js文件进行遍历赋值操作
  const value = enModulesFiles(modulePath);//加载当前的js文件
  for (var pro in value.default) {
    enModuleObj[pro] = value.default[pro];//遍历将当前的js文件中的数据赋给enModuleObj,最后返回,最终enModulesFiles中就包含所有的翻译数据
  }
  return enModuleObj;
}, {});

const zhModulesFiles = require.context('./zh', true, /.js$/);
const zhLocaleModules = zhModulesFiles.keys().reduce((modules, modulePath) => {
  const value = zhModulesFiles(modulePath);
  for (var pro in value.default) {
    zhModuleObj[pro] = value.default[pro];
  }
  return zhModuleObj;
}, {});

Vue.use(VueI18n);

const messages = {
  en: {
    ...elementEnLocale,
    ...enLocaleModules
  },
  zh: {
    ...elementZhLocale,
    ...zhLocaleModules
  },
};
export function getLanguage() {
  const chooseLanguage = Cookies.get('language');
  if (chooseLanguage) return chooseLanguage;

  // navigator.language 方法可以获取浏览器当前使用的语言
  const language = (navigator.language || navigator.browserLanguage).toLowerCase();
  const locales = Object.keys(messages);
  for (const locale of locales) {
    if (language.indexOf(locale) > -1) {
      return locale;
    }
  }
  return 'en';//默认返回en
}
const i18n = new VueI18n({
  // set locale
  // options: en | zh | es
  locale: getLanguage(),
  // set locale messages
  messages
});

export default i18n;

3. main.js 中引入

import Vue from 'vue' 
import App from './App.vue' 
import i18n from './langurage' 
Vue.config.productionTip = false 

// 挂载 i18n 
new Vue({
  el: '#app',
  i18n,
  render: h => h(App),
});


4. 在项目中使用:

格式是 $t("hello")$t('table.date');
效果: image.png

image.png

5.语言切换模块

image.png

<template>
  <el-dropdown trigger="click" class="international" @command="handleSetLanguage">
    <div>
      <svg-icon class-name="international-icon" icon-class="language" />
    </div>
    <el-dropdown-menu slot="dropdown">
      <el-dropdown-item :disabled="language==='zh'" command="zh">
        中文
      </el-dropdown-item>
      <el-dropdown-item :disabled="language==='en'" command="en">
        English
      </el-dropdown-item>
    </el-dropdown-menu>
  </el-dropdown>
</template>

<script>
export default {
  computed: {
    language() {
      return this.$store.getters.language;
    }
  },
  methods: {
    handleSetLanguage(lang) {
      this.$i18n.locale = lang;
      this.$store.dispatch('app/setLanguage', lang);
      this.$router.go(0); // 每次切换都刷新一遍路由,解决项目中部分刷新中英文没有翻译的问题
      // this.$message({
      //   message: 'Switch Language Success',
      //   type: 'success'
      // });
    }
  }
};
</script>

6. 动态菜单如何处理:

在utils文件中定义一个i18n.js文件:

// translate router.meta.title, be used in breadcrumb sidebar tagsview
export function generateTitle(title) {
  const hasKey = this.$t('route.' + title);

  if (hasKey) {
    // $t :this method from vue-i18n, inject in @/lang/index.js
    const translatedTitle = this.$t('route.' + title);

    return translatedTitle;
  }
  return title;
}

使用:

在页面中引用:

<template>
  <el-breadcrumb class="app-breadcrumb" separator="/">
    <transition-group name="breadcrumb">
      <el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
        <span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">
          {{ generateTitle(reverseTitle(item.name)) }}
        </span>
        <a v-else @click.prevent="handleLink(item, index)">{{ generateTitle(reverseTitle(item.name)) }}</a>
      </el-breadcrumb-item>
    </transition-group>
  </el-breadcrumb>
</template>

import { generateTitle } from '@/utils/i18n';