mirror of
https://github.com/iczer/vue-antd-admin
synced 2025-04-06 04:00:06 +08:00
chore: optimize the i18n code of router; 🌟
This commit is contained in:
parent
d91f3a8661
commit
d21a2ab062
@ -6,17 +6,16 @@
|
|||||||
<h1>{{systemName}}</h1>
|
<h1>{{systemName}}</h1>
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<i-menu @i18nComplete="setRoutesI18n" :i18n="menuI18n" :theme="theme" :collapsed="collapsed" :options="menuData" @select="onSelect" class="menu"/>
|
<i-menu :theme="theme" :collapsed="collapsed" :options="menuData" @select="onSelect" class="menu"/>
|
||||||
</a-layout-sider>
|
</a-layout-sider>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import IMenu from './menu'
|
import IMenu from './menu'
|
||||||
import {mapState, mapMutations} from 'vuex'
|
import {mapState} from 'vuex'
|
||||||
export default {
|
export default {
|
||||||
name: 'SideMenu',
|
name: 'SideMenu',
|
||||||
components: {IMenu},
|
components: {IMenu},
|
||||||
inject: ['menuI18n'],
|
|
||||||
props: {
|
props: {
|
||||||
collapsible: {
|
collapsible: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -47,8 +46,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
onSelect (obj) {
|
onSelect (obj) {
|
||||||
this.$emit('menuSelect', obj)
|
this.$emit('menuSelect', obj)
|
||||||
},
|
}
|
||||||
...mapMutations('setting', ['setRoutesI18n'])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
**/
|
**/
|
||||||
import Menu from 'ant-design-vue/es/menu'
|
import Menu from 'ant-design-vue/es/menu'
|
||||||
import Icon from 'ant-design-vue/es/icon'
|
import Icon from 'ant-design-vue/es/icon'
|
||||||
import '@/utils/Objects'
|
|
||||||
|
|
||||||
const {Item, SubMenu} = Menu
|
const {Item, SubMenu} = Menu
|
||||||
|
|
||||||
@ -78,21 +77,15 @@ export default {
|
|||||||
return this.theme == 'light' ? this.theme : 'dark'
|
return this.theme == 'light' ? this.theme : 'dark'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeMount() {
|
|
||||||
let CN = this.generateI18n(new Object(), this.options, 'name')
|
|
||||||
let US = this.generateI18n(new Object(), this.options, 'path')
|
|
||||||
this.$i18n.setLocaleMessage('CN', CN)
|
|
||||||
this.$i18n.setLocaleMessage('US', US)
|
|
||||||
if(this.i18n) {
|
|
||||||
Object.keys(this.i18n).forEach(key => {
|
|
||||||
this.$i18n.mergeLocaleMessage(key, this.i18n[key])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.$emit('i18nComplete', this.$i18n._getMessages())
|
|
||||||
},
|
|
||||||
created () {
|
created () {
|
||||||
this.updateMenu()
|
this.updateMenu()
|
||||||
this.formatOptions(this.options, '')
|
// 自定义国际化配置
|
||||||
|
if(this.i18n && this.i18n.messages) {
|
||||||
|
const messages = this.i18n.messages
|
||||||
|
Object.keys(messages).forEach(key => {
|
||||||
|
this.$i18n.mergeLocaleMessage(key, messages[key])
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
collapsed (val) {
|
collapsed (val) {
|
||||||
@ -198,16 +191,6 @@ export default {
|
|||||||
return this.getSelectedKey(route.parent)
|
return this.getSelectedKey(route.parent)
|
||||||
}
|
}
|
||||||
return route.path
|
return route.path
|
||||||
},
|
|
||||||
generateI18n(lang, options, valueKey) {
|
|
||||||
options.forEach(menu => {
|
|
||||||
let keys = menu.fullPath.substring(1).split('/').concat('name')
|
|
||||||
lang.assignProps(keys, menu[valueKey])
|
|
||||||
if (menu.children) {
|
|
||||||
this.generateI18n(lang, menu.children, valueKey)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return lang
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render (h) {
|
render (h) {
|
||||||
|
@ -50,8 +50,7 @@ export default {
|
|||||||
},
|
},
|
||||||
provide() {
|
provide() {
|
||||||
return{
|
return{
|
||||||
layoutMinHeight: minHeight,
|
layoutMinHeight: minHeight
|
||||||
menuI18n: require('@/router/i18n').default
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page-layout">
|
<div class="page-layout">
|
||||||
<page-header :i18n="routesI18n" :breadcrumb="breadcrumb" :title="pageTitle" :logo="logo" :avatar="avatar">
|
<page-header :breadcrumb="breadcrumb" :title="pageTitle" :logo="logo" :avatar="avatar">
|
||||||
<slot name="action" slot="action"></slot>
|
<slot name="action" slot="action"></slot>
|
||||||
<slot slot="content" name="headerContent"></slot>
|
<slot slot="content" name="headerContent"></slot>
|
||||||
<div slot="content" v-if="!this.$slots.headerContent && desc">
|
<div slot="content" v-if="!this.$slots.headerContent && desc">
|
||||||
@ -37,14 +37,10 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
let i18n = this.routesI18n
|
|
||||||
Object.keys(i18n).forEach(key => {
|
|
||||||
this.$i18n.mergeLocaleMessage(key, i18n[key])
|
|
||||||
})
|
|
||||||
this.page = this.$route.meta.page
|
this.page = this.$route.meta.page
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState('setting', ['layout', 'routesI18n']),
|
...mapState('setting', ['layout']),
|
||||||
pageTitle() {
|
pageTitle() {
|
||||||
let pageTitle = this.page && this.page.title
|
let pageTitle = this.page && this.page.title
|
||||||
return this.title || this.$t(pageTitle) || this.routeName
|
return this.title || this.$t(pageTitle) || this.routeName
|
||||||
|
@ -26,7 +26,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState('setting', ['isMobile', 'multiPage', 'animate', 'routesI18n', 'dustbins']),
|
...mapState('setting', ['isMobile', 'multiPage', 'animate', 'dustbins']),
|
||||||
desc() {
|
desc() {
|
||||||
return this.page.desc
|
return this.page.desc
|
||||||
},
|
},
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<a-divider v-if="isMobile" type="vertical" />
|
<a-divider v-if="isMobile" type="vertical" />
|
||||||
<a-icon v-if="layout === 'side'" class="trigger" :type="collapsed ? 'menu-unfold' : 'menu-fold'" @click="toggleCollapse"/>
|
<a-icon v-if="layout === 'side'" class="trigger" :type="collapsed ? 'menu-unfold' : 'menu-fold'" @click="toggleCollapse"/>
|
||||||
<div v-if="layout == 'head' && !isMobile" class="admin-header-menu">
|
<div v-if="layout == 'head' && !isMobile" class="admin-header-menu">
|
||||||
<i-menu class="head-menu" style="height: 64px; line-height: 64px;box-shadow: none" @i18nComplete="setRoutesI18n" :i18n="menuI18n" :theme="headerTheme" mode="horizontal" :options="menuData" @select="onSelect"/>
|
<i-menu class="head-menu" style="height: 64px; line-height: 64px;box-shadow: none" :theme="headerTheme" mode="horizontal" :options="menuData" @select="onSelect"/>
|
||||||
</div>
|
</div>
|
||||||
<div :class="['admin-header-right', headerTheme]">
|
<div :class="['admin-header-right', headerTheme]">
|
||||||
<header-search class="header-item" />
|
<header-search class="header-item" />
|
||||||
@ -43,7 +43,6 @@ export default {
|
|||||||
name: 'AdminHeader',
|
name: 'AdminHeader',
|
||||||
components: {IMenu, HeaderAvatar, HeaderNotice, HeaderSearch},
|
components: {IMenu, HeaderAvatar, HeaderNotice, HeaderSearch},
|
||||||
props: ['collapsed', 'menuData'],
|
props: ['collapsed', 'menuData'],
|
||||||
inject: ['menuI18n'],
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
langList: [
|
langList: [
|
||||||
@ -73,7 +72,7 @@ export default {
|
|||||||
onSelect (obj) {
|
onSelect (obj) {
|
||||||
this.$emit('menuSelect', obj)
|
this.$emit('menuSelect', obj)
|
||||||
},
|
},
|
||||||
...mapMutations('setting', ['setLang', 'setRoutesI18n'])
|
...mapMutations('setting', ['setLang'])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -44,7 +44,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState('setting', ['multiPage', 'animate', 'layout', 'dustbins', 'routesI18n']),
|
...mapState('setting', ['multiPage', 'animate', 'layout', 'dustbins']),
|
||||||
menuItemList() {
|
menuItemList() {
|
||||||
return [
|
return [
|
||||||
{ key: '1', icon: 'vertical-right', text: this.$t('closeLeft') },
|
{ key: '1', icon: 'vertical-right', text: this.$t('closeLeft') },
|
||||||
@ -57,10 +57,6 @@ export default {
|
|||||||
const route = this.$route
|
const route = this.$route
|
||||||
this.pageList.push(route)
|
this.pageList.push(route)
|
||||||
this.activePage = route.fullPath
|
this.activePage = route.fullPath
|
||||||
let i18n = this.routesI18n
|
|
||||||
Object.keys(i18n).forEach(key => {
|
|
||||||
this.$i18n.mergeLocaleMessage(key, i18n[key])
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route': function (newRoute) {
|
'$route': function (newRoute) {
|
||||||
|
11
src/main.js
11
src/main.js
@ -7,22 +7,15 @@ import Viser from 'viser-vue'
|
|||||||
import '@/mock'
|
import '@/mock'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import 'animate.css/source/animate.css'
|
import 'animate.css/source/animate.css'
|
||||||
import VueI18n from 'vue-i18n'
|
|
||||||
import Plugins from '@/plugins'
|
import Plugins from '@/plugins'
|
||||||
|
import {initI18n} from '@/utils/i18n'
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
Vue.use(Viser)
|
Vue.use(Viser)
|
||||||
Vue.use(Antd)
|
Vue.use(Antd)
|
||||||
Vue.use(VueI18n)
|
|
||||||
Vue.use(Plugins)
|
Vue.use(Plugins)
|
||||||
|
|
||||||
|
const i18n = initI18n(router, 'CN', 'US')
|
||||||
|
|
||||||
const i18n = new VueI18n({
|
|
||||||
locale: 'CN',
|
|
||||||
fallbackLocale: 'US',
|
|
||||||
silentFallbackWarn: true
|
|
||||||
})
|
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
router,
|
router,
|
||||||
|
@ -16,11 +16,15 @@ const timeList = [
|
|||||||
CN: '中午好',
|
CN: '中午好',
|
||||||
HK: '中午好',
|
HK: '中午好',
|
||||||
US: 'Good afternoon',
|
US: 'Good afternoon',
|
||||||
|
},{
|
||||||
|
CN: '下午好',
|
||||||
|
HK: '下午好',
|
||||||
|
US: 'Good afternoon',
|
||||||
},{
|
},{
|
||||||
CN: '晚上好',
|
CN: '晚上好',
|
||||||
HK: '晚上好',
|
HK: '晚上好',
|
||||||
US: 'Good evening',
|
US: 'Good evening',
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
const welcomeMessages = [
|
const welcomeMessages = [
|
||||||
@ -56,7 +60,8 @@ Random.extend({
|
|||||||
timeFix () {
|
timeFix () {
|
||||||
const time = new Date()
|
const time = new Date()
|
||||||
const hour = time.getHours()
|
const hour = time.getHours()
|
||||||
return hour < 9 ? timeList[0] : (hour <= 11 ? timeList[1] : (hour <= 13 ? timeList[2] : (hour <= 20 ? timeList[3] : timeList[4])))
|
return hour < 9
|
||||||
|
? timeList[0] : (hour <= 11 ? timeList[1] : (hour <= 13 ? timeList[2] : (hour <= 20 ? timeList[3] : timeList[4])))
|
||||||
},
|
},
|
||||||
avatar () {
|
avatar () {
|
||||||
return this.pick(avatars)
|
return this.pick(avatars)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
export default {
|
module.exports = {
|
||||||
|
messages: {
|
||||||
CN: {
|
CN: {
|
||||||
home: {name: '首页'},
|
home: {name: '首页'},
|
||||||
},
|
},
|
||||||
@ -53,3 +54,4 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -6,7 +6,6 @@ export default {
|
|||||||
isMobile: false,
|
isMobile: false,
|
||||||
animates: ADMIN.animates,
|
animates: ADMIN.animates,
|
||||||
palettes: ADMIN.palettes,
|
palettes: ADMIN.palettes,
|
||||||
routesI18n: {},
|
|
||||||
dustbins: [],
|
dustbins: [],
|
||||||
...config,
|
...config,
|
||||||
},
|
},
|
||||||
@ -38,9 +37,6 @@ export default {
|
|||||||
setLang(state, lang) {
|
setLang(state, lang) {
|
||||||
state.lang = lang
|
state.lang = lang
|
||||||
},
|
},
|
||||||
setRoutesI18n(state, i18n) {
|
|
||||||
state.routesI18n = i18n
|
|
||||||
},
|
|
||||||
setHideSetting(state, hideSetting) {
|
setHideSetting(state, hideSetting) {
|
||||||
state.hideSetting = hideSetting
|
state.hideSetting = hideSetting
|
||||||
},
|
},
|
||||||
|
67
src/utils/i18n.js
Normal file
67
src/utils/i18n.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import VueI18n from 'vue-i18n'
|
||||||
|
import routesI18n from '@/router/i18n'
|
||||||
|
import './Objects'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建 i18n 配置
|
||||||
|
* @param router 路由
|
||||||
|
* @param locale 本地化语言
|
||||||
|
* @param fallback 回退语言
|
||||||
|
* @returns {VueI18n}
|
||||||
|
*/
|
||||||
|
function initI18n(router, locale, fallback) {
|
||||||
|
Vue.use(VueI18n)
|
||||||
|
const options = router.options.routes.find(item => item.path === '/').children
|
||||||
|
formatOptions(options, '')
|
||||||
|
const CN = generateI18n(new Object(), options, 'name')
|
||||||
|
const US = generateI18n(new Object(), options, 'path')
|
||||||
|
const i18n = new VueI18n({
|
||||||
|
locale,
|
||||||
|
fallbackLocale: fallback,
|
||||||
|
silentFallbackWarn: true,
|
||||||
|
messages: {CN, US}
|
||||||
|
})
|
||||||
|
const messages = routesI18n.messages
|
||||||
|
Object.keys(messages).forEach(key => {
|
||||||
|
i18n.mergeLocaleMessage(key, messages[key])
|
||||||
|
})
|
||||||
|
return i18n
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 router options 配置生成 国际化语言
|
||||||
|
* @param lang
|
||||||
|
* @param options
|
||||||
|
* @param valueKey
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
function generateI18n(lang, options, valueKey) {
|
||||||
|
options.forEach(menu => {
|
||||||
|
let keys = menu.fullPath.substring(1).split('/').concat('name')
|
||||||
|
lang.assignProps(keys, menu[valueKey])
|
||||||
|
if (menu.children) {
|
||||||
|
generateI18n(lang, menu.children, valueKey)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return lang
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化 router options,生成 fullPath
|
||||||
|
* @param options
|
||||||
|
* @param parentPath
|
||||||
|
*/
|
||||||
|
function formatOptions(options, parentPath) {
|
||||||
|
options.forEach(route => {
|
||||||
|
let isFullPath = route.path.substring(0, 1) === '/'
|
||||||
|
route.fullPath = isFullPath ? route.path : parentPath + '/' + route.path
|
||||||
|
if (route.children) {
|
||||||
|
formatOptions(route.children, route.fullPath)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
initI18n
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user