前端Vue实现国际化

国际化实现原理

假设我们有一个变量 msg,但是这个 msg 有两个值,一个是 hello,一个是 你好,现在需要我们根据需要切换 msg 的值,如何做呢?

// 定义 msg 值的数据源
const msgList = {
  en: {
    msg: 'hello'
  },
  zh: {
    msg: '你好'
  }
}
// 定义切换变量
let locale = 'en'
// 定义赋值函数
function t(key) {
  return msgList[locale][key]
}
// 为 msg 赋值
let msg = t('msg')
console.log(msg) // hello

总结

  • 通过一个变量来控制语言环境
  • 所有语言环境下的数据源要预先定义好
  • 通过一个方法来获取当前语言下指定属性的值
  • 该值为国际化下展示值

基于 vue-i18n V9(Vue3 适用) 的国际化实现方案

安装 vue-i8n

npm install vue-i18n@next

src目录下创建 i18n/index.js 文件

创建数据源、创建 locale 语言变量、初始化 i18n 实例

// index.js
import { createI18n } from 'vue-i18n'

const messages = {
  en: {
    msg: {
      test: 'hello'
    }
  },
  zh: {
    msg: {
      test: '你好'
    }
  }
}

const locale = 'en'
const i18n = createI18n({
  legacy: false, // 使用了Vue3 composition API的话这项一定要为false
  globalInjection: true, // 全局使用 t 函数
  locale,
  messages
})

export default i18n

注册 i18n 实例

// main.js
import i18n from '@/i18n'
app.use(i18n).mount('#app')

测试

<template>
  <div class="">
    {{ $t('msg.test') }} 
  div>
template>

<script setup>
import {} from 'vue'
script>

<style lang="scss" scoped>style>

项目中完成国际化

封装 langSelect 组件用于修改 locale

  1. 定义 store/app.js
export default {
  namespaced: true,
  state: {
    language: window.localStorage.getItem('language') || 'zh'
  },
  mutations: {
    /**
     * 设置国际化
     */
    setLanguage(state, lang) {
      window.localStorage.setItem('language', lang)
      state.language = lang
    }
  },
  actions: {}
}
  1. 创建 LangSelect 组件
<template>
  <el-dropdown
    trigger="click"
    class="international"
    @command="handleSetLanguage"
  >
    <div>
      <el-tooltip content="国际化">
        <svg-icon icon="language">svg-icon>
      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 { computed } from 'vue'
import { useStore } from 'vuex'
import { useI18n } from 'vue-i18n'

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

// 切换语言
const i18n = useI18n()
const handleSetLanguage = lang => {
  i18n.locale.value = lang // 切换 i18n 的 locale
  store.commit('app/setLanguage', lang) // 修改 vuex 中的 language
}
script>

<style scoped>style>

前端Vue实现国际化_第1张图片

导入 el-locale 语言包

在ElementUi中可以配合vue-i18n进行国际化,详细可看文档
但是在ElementPlus中不行(切换完语言需要刷新页面才能生效),只能临时进行处理:

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import en from 'element-plus/lib/locale/lang/en'
import store from '@/store'

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

注意:使用的elementPlus版本为1.1.0-beta.15,版本不同不同文件位置可能不一样,引入的时候需要注意

创建自定义语言包

在 i18n 下新建 lang 文件夹,下面有 en.js 和 zh.js 两个语言包,在 i18n 下的 index.js 中引入

import { createI18n } from 'vue-i18n'
import zhLocale from './lang/zh'
import enLocale from './lang/en'

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

const locale = 'zh'
const i18n = createI18n({
  legacy: false, // 使用了Vue3 composition API的话这项一定要为false
  globalInjection: true, // 全局使用 t 函数
  locale,
  messages
})

export default i18n

en.js 和 zh.js 需要自己编写,分别是英文与中文环境下字段的数据:

前端Vue实现国际化_第2张图片
前端Vue实现国际化_第3张图片

处理项目国际化内容

将页面中写死的数据改为用 $t 函数,比如登录页的标题:

<h1 class="title">用户登录div>
<h1 class="title">{{ $t('msg.login.title') }}div>

vue 组件中:

const loginRules = ref({
  username: [
    {
      required: true,
      trigger: 'blur',
      message: '用户名为必填项'
    }
  ]
})
import { useI18n } from 'vue-i18n'

const i18n = useI18n()
const loginRules = ref({
  username: [
    {
      required: true,
      trigger: 'blur',
      message: i18n.t('msg.login.usernameRule')
    }
  ]
})

js 中:

import i18n from '@/i18n'
export const validatePassword = (rule, value, callback) => {
  if (value.length < 6) {
    callback(new Error(i18n.global.t('msg.login.passwordRule')))
  } else {
    callback()
  }
}

你可能感兴趣的:(Vue,vue.js,前端,javascript)