Vue+Springboot打造前后端分离的企业管理系统 — Vue前端国际化支持详解

系统前端Vue的国际化应用vue-i18n插件支持,按照vue-i18n插件的使用规范即可实现界面的多语言支持,非常简单。具体应用步骤如下:
一、安装插件
npm install vue-i18n --save

二、在项目src下新建一个i18n目录,创建index.js

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import { getObjArr } from '@/utils/storage'

// 启用i18n
Vue.use(VueI18n)

const i18n = new VueI18n({
  locale: getObjArr('locale') || 'zh_CN', // 默认为中文
  messages: {
    'zh_CN': require('@/assets/messages/messages_zh_CN.js'),
    'en_US': require('@/assets/messages/messages_en_US.json')
  }
})

export default i18n


三、在main.js中引入插件

1.引入i18n国际化插件。

import i18n from './i18n'

2.将i18n注入到vue实例中

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

四、文本Messages文件格式(js文件)

在项目的assets目录下新建一个messages目录,后面所有前端页面的多语言消息文本将统一保存在此目录下,如果喜欢,使用json文件格式保存message本文也是可以的。messages的js文件示例如下。

简体中文(messages_zh_CN.js):

Vue+Springboot打造前后端分离的企业管理系统 — Vue前端国际化支持详解

对应的messages_en_US.js格式与messages_zh_CN.js一样,只需要把中文改为英文即可,如下:

Vue+Springboot打造前后端分离的企业管理系统 — Vue前端国际化支持详解

五、在axios设置请求头,将语言环境与后台同步

前端的语言环境需要与后台同步才能保持前后台统一系统语境,通过在axios中的拦截中注入语言变量的传递。

import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import { getObjArr } from '@/utils/storage'

const QS = require('querystring')
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url, 后端应用服务器URL,在环境设置文件中设置
  withCredentials: true, 
  timeout: 5000 
})

// request interceptor
service.interceptors.request.use(
  config => {
    // 取当前的语言环境给请求头
    config.headers['locale'] = getObjArr('locale')
    if (config.method === 'post') {
      config.data = QS.stringify(config.data) // 防止post参数无法传到后台
    }
    if (store.getters.token) {
      config.headers['HecateX-Token'] = getToken()
    }
    return config
  },
  error => {
    console.log(error) // for debug
    return Promise.reject(error)
  }
)

// response interceptor
service.interceptors.response.use(
  response => {
    const res = response.data
    if (res.code !== 200) {
      Message({
        message: res.message || 'Error',
        type: 'error',
        duration: 5 * 1000
      })
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res
    }
  },
  error => {
    console.log('err' + error) // for debug
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)
export default service

六、在前端页面通过指定的消息代码完成页面的动态渲染

在前端页面实际使用消息代码进行动态渲染时,需要注意的是在html中的引用与在js中引用的表达式稍有差异。

html文件(template标签中使用)需要加{{}}:
<h3 class="title">{{$t('messages.login.title')}}</h3>
        <el-input
          ref="username"
          v-model="loginForm.username"
          :placeholder="$t('messages.login.username_placeholder')"
          name="username"
          type="text"
          tabindex="1"
          auto-complete="on"

        />

js文件(script标签中使用):
  callback(new Error( this.$t('messages.login.validate_password')))

实际代码例子:

<template>
  <div id="paper">
    <el-button type="text" style="font-size: 15px; color: #bbbbbb;" @click="dialogFormVisible = true">
      {{ $t('messages.register.new_user_btn') }}
    </el-button>
    <el-dialog :title="$t('messages.register.title')" :visible.sync="dialogFormVisible" width="25%" @close="clear">
      <el-form
        v-loading="loading"
        :model="loginForm"
        :rules="rules"
        class="login-container"
        label-position="left"
        label-width="0px"
      >
        <h3 class="login_title">{{ $t('messages.register.title') }}</h3>
        <el-form-item prop="username">
          <el-input
            v-model="loginForm.username"
            type="text"
            auto-complete="off"
            :placeholder="$t('messages.register.username')"
          />
        </el-form-item>
        <el-form-item prop="password">
          <el-input
            v-model="loginForm.password"
            type="password"
            auto-complete="off"
            :placeholder="$t('messages.register.password')"
          />
        </el-form-item>
        <el-form-item>
          <el-input
            v-model="loginForm.name"
            type="text"
            auto-complete="off"
            :placeholder="$t('messages.register.real_name')"
          />
        </el-form-item>
        <el-form-item>
          <el-input
            v-model="loginForm.phone"
            type="text"
            auto-complete="off"
            :placeholder="$t('messages.register.phone')"
          />
        </el-form-item>
        <el-form-item>
          <el-input
            v-model="loginForm.email"
            type="text"
            auto-complete="off"
            :placeholder="$t('messages.register.email')"
          />
        </el-form-item>
        <el-form-item style="width: 100%">
          <el-button
            type="primary"
            style="width: 40%; background: #505458; border: none"
            @click="register"
          >{{ $t('messages.register.register_btn') }}</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'Register',
  data() {
    return {
      rules: {
        // eslint-disable-next-line no-undef
        username: [{ required: true, message: this.$t('messages.register.username_notallow_empty'), trigger: 'blur' }],
        // eslint-disable-next-line no-undef
        password: [{ required: true, message: this.$t('messages.register.username_notallow_empty'), trigger: 'blur' }]
      },
      checked: true,
      loginForm: {
        username: '',
        password: '',
        name: '',
        phone: '',
        email: ''
      },
      loading: false
    }
  },
  methods: {
    register() {
      var _this = this

      this.$axios
        .post('/register', {
          username: this.loginForm.username,
          password: this.loginForm.password,
          name: this.loginForm.name,
          phone: this.loginForm.phone,
          email: this.loginForm.email
        })
        .then(resp => {
          if (resp.data.code === 200) {
            // eslint-disable-next-line no-undef
            this.$alert(this.$t('messages.common.user_register_success'), this.$t('messages.common.information'), {
              // eslint-disable-next-line no-undef
              confirmButtonText: this.$t('messages.common.confirmButtonText')
            })
            _this.$router.replace('/login')
          } else {
            // eslint-disable-next-line no-undef
            this.$alert(resp.data.message, this.$t('messages.common.information'), {
              // eslint-disable-next-line no-undef
              confirmButtonText: this.$t('messages.common.confirmButtonText')
            })
          }
        })
      // eslint-disable-next-line no-unused-vars
        .catch(failResponse => {})
    }
  }
}
</script>