vue3 + Element-plus 开发后台管理系统(21)

346 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第21天,点击查看活动详情

后台项目前端综合解决方案之通用功能开发

上一篇简单的介绍了一下 i18n 的基本用法,下边就来看一看在项目中如何使用 i18n 进行国际化

项目中完成国际化主要分为以下几步

1、封装 langSelect 组件用于修改 locale

2、导入 el-locale 语言包

3、创建自定义语言包

封装 langSelect 组件

1、定义 store/app.js

import { LANG } from '@/constant'
import { getItem, setItem } from '@/utils/storage'
export default {
  namespaced: true,
  state: () => ({
    language: getItem(LANG) || 'zh'
  }),
  mutations: {
    // 设置国际化
    setLanguage(state, lang) {
      setItem(LANG, lang)
      state.language = lang
    }
  },
  actions: {}
}

2、在 constant 中定义变量

// 国际化
export const LANG = 'language'

3、创建 components/LangSelect/index

<template>
  <el-dropdown
    trigger="click"
    class="international"
    @command="handleSetLanguage"
  >
    <div>
      <el-tooltip content="国际化" :effect="effect">
        <svg-icon icon="language" />
      </el-tooltip>
    </div>
    <template #dropdown>
      <el-dropdown-menu>
        <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>
    </template>
  </el-dropdown>
</template>

<script setup>
import { useI18n } from 'vue-i18n'
import { defineProps, computed } from 'vue'
import { useStore } from 'vuex'
import { ElMessage } from 'element-plus'

defineProps({
  effect: {
    type: String,
    default: 'dark',
    validator: function(value) {
      // 这个值必须匹配下列字符串中的一个
      return ['dark', 'light'].indexOf(value) !== -1
    }
  }
})

const store = useStore()
const language = computed(() => store.getters.language)

// 切换语言的方法
const i18n = useI18n()
const handleSetLanguage = lang => {
  i18n.locale.value = lang
  store.commit('app/setLanguage', lang)
  ElMessage.success('更新成功')
}
</script>

4、在 navbar 中导入 LangSelect

<template>
  <div class="navbar">
    <div class="right-menu">
      <lang-select class="right-menu-item hover-effect" />
    </div>
  </div>
</template>

<script setup>
import LangSelect from '@/components/LangSelect'
</script>

<style lang="scss" scoped>
.navbar {
  .right-menu {
    ::v-deep .right-menu-item {
      display: inline-block;
      padding: 0 18px 0 0;
      font-size: 24px;
      color: #5a5e66;
      vertical-align: text-bottom;

      &.hover-effect {
        cursor: pointer;
      }
    }
  }
}
</style>

element-plus 国际化处理

至此,我们国际化的基本功能已经实现了,接下来就是处理对应的语言包,有了对应的语言包就可以实现整个项目中的国际化处理了

那么对于语言包来说,我们整个项目可以分成两个部分

1、element-plus 语言包:用来处理 element 组件的国际化功能

2、自定义语言包:用来处理非 element 组件的国际化功能

  • 处理 element-plus 的语言包

按照正常的逻辑,我们是可以通过 element-ui 配合 vue-i18n 实现国际化功能,但是目前 element-plus 尚未提供配合 vue-i18n 实现国际化的方法

所以,我们这里只能进行临时的处理

1、升级 element-plus 到最新版本

npm i element-plus

2、升级版本之后,左侧 menu 菜单无法正常显示,这是因为 element-plus 修改了 el-submenu 的组件名称

3、到 layout/components/Sidebar/SidebarItem 中,修改 el-submenu 为 el-sub-menu

4、实现国际化,在 plugins/index 中导入 element 的中文、英文语言包

import zhCn from 'element-plus/es/locale/lang/zh-cn'
import en from 'element-plus/lib/locale/lang/en'

5、注册 element 时,根据当前语言选择使用哪种语言包

import store from '@/store'

export default app => {
  app.use(ElementPlus, {
    locale: store.getters.language === 'en' ? en : zhCn
  })
}

自定义语言包国际化处理

处理完了 element 的国际化,接下来我们处理自定义语言包

自定义语言包我们使用 commonJS 到处一个对象,这个对象就是所有的自定义语言对象

至于语言包大家需要根据项目进行配置,在这里只给大家放一个 demo

  • zh.js
export default {
  login: {
    title: '用户登录',
    loginBtn: '登录',
    usernameRule: '用户名为必填项',
    passwordRule: '密码不能少于6位',
  },
  route: {
    profile: '个人中心',
    user: '用户',
    excelImport: 'Excel导入',
    userManage: '员工管理',
    userInfo: '员工信息',
    roleList: '角色列表',
    permissionList: '权限列表',
    article: '文章',
    articleRanking: '文章排名',
    articleCreate: '创建文章',
    articleDetail: '文章详情',
    articleEditor: '文章编辑'
  }
}  
  • en.js
export default {
  login: {
    title: 'User Login',
    loginBtn: 'Login',
    usernameRule: 'Username is required',
    passwordRule: 'Password cannot be less than 6 digits',
  },
  route: {
    profile: 'Profile',
    user: 'user',
    excelImport: 'ExcelImport',
    userManage: 'EmployeeManage',
    userInfo: 'UserInfo',
    roleList: 'RoleList',
    permissionList: 'PermissionList',
    article: 'article',
    articleRanking: 'ArticleRanking',
    articleCreate: 'ArticleCreate',
    articleDetail: 'ArticleDetail',
    articleEditor: 'ArticleEditor'
  }
 }

lang/index 中导入语言包

import mZhLocale from './lang/zh'
import mEnLocale from './lang/en'

message 中注册语言包

const messages = {
  en: {
    msg: {
      ...mEnLocale
    }
  },
  zh: {
    msg: {
      ...mZhLocale
    }
  }
}