Vue-admin-template 添加国际化

1.背景

在全球发展的趋势下,国际化,成为各种软件不可或缺的一部分…

使用Vue-admin-template作为基本框架(基于Element-UI),添加国际化插件i18n

2.开发环境

  1. Vue-admin-template(其他应该也可以使用)
  2. element-ui: “2.4.6”
  3. vue: “2.5.17”
  4. vue-i18n: “^8.8.2”
  5. vue-router: “3.0.1”
  6. vuex: “3.0.1”

3.安装i18n

npm i vue-i18n

4.添加语言包

在这里插入图片描述

lang/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
import enLocale from './en'
import zhLocale from './zh'

Vue.use(VueI18n)

const messages = {
  en: {
    ...enLocale,
    ...elementEnLocale
  },
  zh: {
    ...zhLocale,
    ...elementZhLocale
  }
}

const i18n = new VueI18n({
  // set locale
  // options: en | zh | es
  locale: Cookies.get('language') || 'en',
  // set locale messages
  messages
})

export default i18n

zh.js(中文语言包)
export default {
  route: {
    dashboard: '首页',
    introduction: '简述'
  }
  role: {
    permission: '权限'
  },
  user: {
    uname: '用户名',
    role: '角色',
    sex: '性别'
  }
}

可根据实际情况,自行添加扩展

en.js(英文语言包)
export default {
  route: {
    dashboard: 'Dashboard',
    introduction: 'Introduction'
  }
  role: {
    permission: 'Permission'
  },
  user: {
    uname: 'User Name',
    role: 'Role',
    sex: 'Sex'
  }
}

5.添加getters,便于获取当前语言

在这里插入图片描述

const getters = {
  ......
  language: state => state.app.language
}
export default getters

6.main.js中添加依赖

import ElementUI from 'element-ui' //基于Element-UI
import i18n from './lang'

Vue.use(ElementUI, {
  i18n: (key, value) => i18n.t(key, value)
})

new Vue({
  el: '#app',
  ......
  i18n,
  render: h => h(App)
})

7.添加语言切换下拉框组件

在这里插入图片描述

LangSelect/index.vue

<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('setLanguage', lang)
      this.$message({
        message: 'Switch Language Success',
        type: 'success'
      })
    }
  }
}
</script>

8.添加切换语言下拉框到头部中

图标可以替换为别的,不然显示的是一片白色

在这里插入图片描述

Navbar.vue
<template>
  <div class="navbar">
    <hamburger :toggle-click="toggleSideBar" :is-active="sidebar.opened" class="hamburger-container"/>
    <breadcrumb />
    <div class="right-menu">
      <template>
        <lang-select class="right-menu-item hover-effect"/>
      </template>
      <el-dropdown class="avatar-container  right-menu-item hover-effect" trigger="click">
        <div class="avatar-wrapper">
          <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar">
          <i class="el-icon-caret-bottom"/>
        </div>
        <el-dropdown-menu slot="dropdown" class="user-dropdown">
          <router-link class="inlineBlock" to="/">
            <el-dropdown-item>
              Home
            </el-dropdown-item>
          </router-link>
          <el-dropdown-item divided>
            <span style="display:block;" @click="logout">LogOut</span>
          </el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import Breadcrumb from '@/components/Breadcrumb'
import Hamburger from '@/components/Hamburger'
import LangSelect from '@/components/LangSelect'

export default {
  components: {
    Breadcrumb,
    Hamburger,
    LangSelect
  },
  computed: {
    ...mapGetters([
      'sidebar',
      'avatar'
    ])
  },
  methods: {
    toggleSideBar() {
      this.$store.dispatch('ToggleSideBar')
    },
    logout() {
      this.$store.dispatch('LogOut').then(() => {
        location.reload() // 为了重新实例化vue-router对象 避免bug
      })
    }
  }
}
</script>

9.添加工具类,用于替换

在这里插入图片描述

i18n.js

// 翻译router.meta。标题,用于面包屑侧边栏tagsview
export function generateTitle(title) {
  const hasKey = this.$te('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
}

10.面包屑中使用

在这里插入图片描述

就是把你之前的固定文字,改为{{ generateTitle(item.meta.title) }}

此处的item.meta.title,就是在路由中配置的meta

一定不要忘记在methods中声明generateTitle方法

在这里插入图片描述

<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(item.meta.title) }}</span>
        <a v-else @click.prevent="handleLink(item)">{{ generateTitle(item.meta.title) }}</a>
      </el-breadcrumb-item>
    </transition-group>
  </el-breadcrumb>
</template>

<script>
import pathToRegexp from 'path-to-regexp'
import { generateTitle } from '@/utils/i18n'

export default {
  data() {
    return {
      levelList: null
    }
  },
  watch: {
    $route() {
      this.getBreadcrumb()
    }
  },
  created() {
    this.getBreadcrumb()
  },
  methods: {
    generateTitle,
    getBreadcrumb() {
      let matched = this.$route.matched.filter(item => item.name)

      const first = matched[0]
      if (first && first.name !== 'dashboard') {
        matched = [{ path: '/dashboard', meta: { title: 'dashboard' }}].concat(matched)
      }

      this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
    },
    pathCompile(path) {
      // To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
      const { params } = this.$route
      var toPath = pathToRegexp.compile(path)
      return toPath(params)
    },
    handleLink(item) {
      const { redirect, path } = item
      if (redirect) {
        this.$router.push(redirect)
        return
      }
      this.$router.push(this.pathCompile(path))
    }
  }
}
</script>


11.其他页面使用

在这里插入图片描述

在你需要替换的地方,直接使用{{ $t('table.cancel') }}

在这里插入图片描述

注意,这里的标签使用的是:lable是Vue的v-bind,而不是普通label

12.注意

这里的table.groupName,就是前面第四步中的语言包。

在这里插入图片描述
在这里插入图片描述

还有就是,路由中的文字,直接写在route下就可以了。因为第9步中已经封装好了

在这里插入图片描述
在这里插入图片描述

Logo

前往低代码交流专区

更多推荐