如何实现多语言转换

524 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情

多语言实现(体力活 - 翻译工作)

**目标**实现国际化语言切换 kazupon.github.io/vue-i18n/zh…

初始化多语言包

本项目使用国际化 i18n 方案。通过 vue-i18n而实现。

第一步,我们需要首先国际化的包

 $ yarn add vue-i18n@8.22.2

第二步,需要单独一个多语言的实例化文件 src/lang/index.js

import Vue from 'vue' // 引入Vue
import VueI18n from 'vue-i18n' // 引入国际化的插件包
import Cookies from 'js-cookie' // 引入cookie包
import elementEN from 'element-ui/lib/locale/lang/en' // 引入饿了么的英文包
import elementZH from 'element-ui/lib/locale/lang/zh-CN' // 引入饿了么的中文包
Vue.use(VueI18n) // 全局注册国际化包// 创建国际化插件的实例
export default new VueI18n({
  // 指定语言类型
  locale: Cookies.get('language') || 'zh', // 从cookie中获取语言类型 获取不到就是中文
  messages: {
    en: {
      ...elementEN // 将饿了么的英文语言包引入
    },
    zh: {
      ...elementZH // 将饿了么的中文语言包引入
    }
  }
})
​

上面的代码的作用是将Element的两种语言导入了

第三步,在main.js中对挂载 i18n的插件,并配置ElementUI的中英切换逻辑

import i18n from '@/lang'// 配置ElementUI的中英切换逻辑
Vue.use(ElementUI, {
  i18n: (key, value) => i18n.t(key, value)
})
​
new Vue({
  el: '#app',
  router,
  store,
  i18n,
  render: h => h(App)
})
​

引入自定义语言包

此时,element已经变成了zh,也就是中文,但是我们常规的内容怎么根据当前语言类型显示?

这里,针对英文和中文,我们可以提供两个不同的语言包 src/lang/zh.js , src/lang/en.js

在index.js中同样引入该语言包

import Vue from 'vue' // 引入Vue
import VueI18n from 'vue-i18n' // 引入国际化的插件包
import Cookies from 'js-cookie' // 引入cookie包
import elementEN from 'element-ui/lib/locale/lang/en' // 引入饿了么的英文包
import elementZH from 'element-ui/lib/locale/lang/zh-CN' // 引入饿了么的中文包
import customZH from './zh' // 引入自定义中文包
import customEN from './en' // 引入自定义英文包Vue.use(VueI18n) // 全局注册国际化包export default new VueI18n({
  locale: Cookies.get('language') || 'en', // 从cookie中获取语言类型 获取不到就是中文
  messages: {
    en: {
      ...elementEN, // 将饿了么的英文语言包引入
      ...customEN
    },
    zh: {
      ...elementZH, // 将饿了么的中文语言包引入
      ...customZH
    }
  }
})
​

在左侧菜单中应用多语言包

自定义语言包的内容怎么使用?

在左侧菜单应用

当我们全局注册i18n的时候,每个组件都会拥有一个 **$t**的方法, $t 方法会被挂载到 vue 原型上

它会根据传入的key,自动的去寻找当前语言的文本, $t('navbar.title')

  1. 我们可以自己添加一些中英翻译, 将头部翻译成中英文

    <div class="app-breadcrumb">
      {{ $t('navbar.title') }}
      <span class="breadBtn">{{ $t('navbar.enjoy') }}</span>
    </div>
    
  2. 我们可以将左侧菜单变成多语言展示文本

layout/components/SidebarItem.vue

<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="$t('route.'+onlyOneChild.name)" />

注意:当文本的值为嵌套时,可以通过 $t('key1.key2.key3...') 的方式获取

现在,我们已经完成了多语言的接入,现在封装切换多语言的组件

封装多语言组件 - 切换语言

封装多语言组件 src/components/Lang/index.vue

<template>
  <el-dropdown trigger="click" @command="changeLanguage">
    <div>
      <svg-icon style="color:#fff;font-size:20px" icon-class="language" />
    </div>
    <el-dropdown-menu slot="dropdown">
      <el-dropdown-item command="zh" :disabled="'zh'=== $i18n.locale ">中文</el-dropdown-item>
      <el-dropdown-item command="en" :disabled="'en'=== $i18n.locale ">en</el-dropdown-item>
    </el-dropdown-menu>
  </el-dropdown>
</template>
​
<script>
import Cookies from 'js-cookie'
export default {
  methods: {
    changeLanguage(lang) {
      Cookies.set('language', lang) // 切换多语言
      this.$i18n.locale = lang // 设置给本地的i18n插件
      this.$message.success('切换多语言成功')
    }
  }
}
// this.$i18n.locale = '语言字符串'  切语言
</script>

component/index.js全局注册

import Lang from './Lang'export default {
  // 插件的初始化, 插件给你提供的全局的功能, 都可以在这里配置
  install(Vue) {
    // 进行组件的全局注册
        ...
    Vue.component('Lang', Lang)
  }
}

在Navbar组件中引入

<!-- 语言包 -->
<lang class="right-menu-item" />
<!-- 全屏组件 -->
<screen-full class="right-menu-item" />
<!-- 放置换肤插件 -->
<theme-picker class="right-menu-item" @change="changeTheme" />

最终效果

image.png

tab页的视图引入

目标: 实现tab页打开路由的功能

当前我们实现的打开页面,看到一个页面之后,另一个页面就会关闭,为了显示更加有效率,我们可以引入多页签组件

在资源目录中,多页签 目录下放置的是 组件和 vuex模块

第一步,将组件TagsView目录放置到**src/components** , 并全局注册

import TagsView from './TagsView'
Vue.component('TagsView', TagsView)

第二步,将Vuex模块**tagsView.js**放置到 src/store/modules

并在store中引入该模块

import tagsView from './modules/tagsView'
const store = new Vuex.Store({
  modules: {
    app,
    settings,
    user,
    permission,
    tagsView
  },
  getters
})

第三步,在**src/layout/Index.vue**中引入该组件

<template>
  <div :class="classObj" class="app-wrapper">
    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
    <sidebar class="sidebar-container" />
    <div class="main-container">
      <div :class="{'fixed-header':fixedHeader}">
        <navbar />
        <!-- 放置tags-view -->
        <tags-view />
      </div>
      <app-main />
    </div>
  </div>
</template>

第四步, 添加缓存控制 layout/components/AppMain.vue

include 配置的是缓存的组件名数组

<template>
  <section class="app-main">
    <!-- 动画效果 -->
    <transition name="fade-transform" mode="out-in">
      <keep-alive :include="cachedViews">
        <router-view :key="key" />
      </keep-alive>
    </transition>
  </section>
</template>
​
<script>
export default {
  name: 'AppMain',
  computed: {
    cachedViews() {
      return this.$store.state.tagsView.cachedViews.map(item => {
        return item[0].toUpperCase() + item.slice(1)
      })
    },
    key() {
      return this.$route.path
    }
  }
}
</script>

效果如下

image.png