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):
对应的messages_en_US.js格式与messages_zh_CN.js一样,只需要把中文改为英文即可,如下:
五、在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>