chore: optimize the i18n code of router; 🌟

master
chenghongxing 5 years ago
parent d91f3a8661
commit d21a2ab062
  1. 8
      src/components/menu/SideMenu.vue
  2. 31
      src/components/menu/menu.js
  3. 3
      src/layouts/AdminLayout.vue
  4. 8
      src/layouts/PageLayout.vue
  5. 2
      src/layouts/PageView.vue
  6. 5
      src/layouts/header/AdminHeader.vue
  7. 6
      src/layouts/tabs/TabsView.vue
  8. 11
      src/main.js
  9. 9
      src/mock/extend/index.js
  10. 100
      src/router/i18n.js
  11. 4
      src/store/modules/setting.js
  12. 67
      src/utils/i18n.js

@ -6,17 +6,16 @@
<h1>{{systemName}}</h1>
</router-link>
</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>
</template>
<script>
import IMenu from './menu'
import {mapState, mapMutations} from 'vuex'
import {mapState} from 'vuex'
export default {
name: 'SideMenu',
components: {IMenu},
inject: ['menuI18n'],
props: {
collapsible: {
type: Boolean,
@ -47,8 +46,7 @@ export default {
methods: {
onSelect (obj) {
this.$emit('menuSelect', obj)
},
...mapMutations('setting', ['setRoutesI18n'])
}
}
}
</script>

@ -31,7 +31,6 @@
**/
import Menu from 'ant-design-vue/es/menu'
import Icon from 'ant-design-vue/es/icon'
import '@/utils/Objects'
const {Item, SubMenu} = Menu
@ -78,21 +77,15 @@ export default {
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 () {
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: {
collapsed (val) {
@ -198,16 +191,6 @@ export default {
return this.getSelectedKey(route.parent)
}
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) {

@ -50,8 +50,7 @@ export default {
},
provide() {
return{
layoutMinHeight: minHeight,
menuI18n: require('@/router/i18n').default
layoutMinHeight: minHeight
}
},
computed: {

@ -1,6 +1,6 @@
<template>
<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 slot="content" name="headerContent"></slot>
<div slot="content" v-if="!this.$slots.headerContent && desc">
@ -37,14 +37,10 @@ export default {
}
},
created() {
let i18n = this.routesI18n
Object.keys(i18n).forEach(key => {
this.$i18n.mergeLocaleMessage(key, i18n[key])
})
this.page = this.$route.meta.page
},
computed: {
...mapState('setting', ['layout', 'routesI18n']),
...mapState('setting', ['layout']),
pageTitle() {
let pageTitle = this.page && this.page.title
return this.title || this.$t(pageTitle) || this.routeName

@ -26,7 +26,7 @@ export default {
}
},
computed: {
...mapState('setting', ['isMobile', 'multiPage', 'animate', 'routesI18n', 'dustbins']),
...mapState('setting', ['isMobile', 'multiPage', 'animate', 'dustbins']),
desc() {
return this.page.desc
},

@ -8,7 +8,7 @@
<a-divider v-if="isMobile" type="vertical" />
<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">
<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 :class="['admin-header-right', headerTheme]">
<header-search class="header-item" />
@ -43,7 +43,6 @@ export default {
name: 'AdminHeader',
components: {IMenu, HeaderAvatar, HeaderNotice, HeaderSearch},
props: ['collapsed', 'menuData'],
inject: ['menuI18n'],
data() {
return {
langList: [
@ -73,7 +72,7 @@ export default {
onSelect (obj) {
this.$emit('menuSelect', obj)
},
...mapMutations('setting', ['setLang', 'setRoutesI18n'])
...mapMutations('setting', ['setLang'])
}
}
</script>

@ -44,7 +44,7 @@ export default {
}
},
computed: {
...mapState('setting', ['multiPage', 'animate', 'layout', 'dustbins', 'routesI18n']),
...mapState('setting', ['multiPage', 'animate', 'layout', 'dustbins']),
menuItemList() {
return [
{ key: '1', icon: 'vertical-right', text: this.$t('closeLeft') },
@ -57,10 +57,6 @@ export default {
const route = this.$route
this.pageList.push(route)
this.activePage = route.fullPath
let i18n = this.routesI18n
Object.keys(i18n).forEach(key => {
this.$i18n.mergeLocaleMessage(key, i18n[key])
})
},
watch: {
'$route': function (newRoute) {

@ -7,22 +7,15 @@ import Viser from 'viser-vue'
import '@/mock'
import store from './store'
import 'animate.css/source/animate.css'
import VueI18n from 'vue-i18n'
import Plugins from '@/plugins'
import {initI18n} from '@/utils/i18n'
Vue.config.productionTip = false
Vue.use(Viser)
Vue.use(Antd)
Vue.use(VueI18n)
Vue.use(Plugins)
const i18n = new VueI18n({
locale: 'CN',
fallbackLocale: 'US',
silentFallbackWarn: true
})
const i18n = initI18n(router, 'CN', 'US')
new Vue({
router,

@ -16,11 +16,15 @@ const timeList = [
CN: '中午好',
HK: '中午好',
US: 'Good afternoon',
},{
CN: '下午好',
HK: '下午好',
US: 'Good afternoon',
},{
CN: '晚上好',
HK: '晚上好',
US: 'Good evening',
},
}
]
const welcomeMessages = [
@ -56,7 +60,8 @@ Random.extend({
timeFix () {
const time = new Date()
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 () {
return this.pick(avatars)

@ -1,55 +1,57 @@
export default {
CN: {
home: {name: '首页'},
},
US: {
home: {name: 'home'},
},
HK: {
home: {name: '首頁'},
dashboard: {
name: 'Dashboard',
workplace: {name: '工作台'},
analysis: {name: '分析頁'}
module.exports = {
messages: {
CN: {
home: {name: '首页'},
},
form: {
name: '表單頁',
basic: {name: '基礎表單'},
step: {name: '分步表單'},
advance: {name: '分步表單'}
US: {
home: {name: 'home'},
},
list: {
name: '列表頁',
query: {name: '查詢表格'},
primary: {name: '標準列表'},
card: {name: '卡片列表'},
search: {
name: '搜索列表',
article: {name: '文章'},
application: {name: '應用'},
project: {name: '項目'}
HK: {
home: {name: '首頁'},
dashboard: {
name: 'Dashboard',
workplace: {name: '工作台'},
analysis: {name: '分析頁'}
},
form: {
name: '表單頁',
basic: {name: '基礎表單'},
step: {name: '分步表單'},
advance: {name: '分步表單'}
},
list: {
name: '列表頁',
query: {name: '查詢表格'},
primary: {name: '標準列表'},
card: {name: '卡片列表'},
search: {
name: '搜索列表',
article: {name: '文章'},
application: {name: '應用'},
project: {name: '項目'}
}
},
details: {
name: '詳情頁',
basic: {name: '基礎詳情頁'},
advance: {name: '高級詳情頁'}
},
result: {
name: '結果頁',
success: {name: '成功'},
error: {name: '失敗'}
},
exception: {
name: '異常頁',
404: {name: '404'},
403: {name: '403'},
500: {name: '500'}
},
components: {
name: '小組件',
taskCard: {name: '任務卡片'},
palette: {name: '顏色複選框'}
}
},
details: {
name: '詳情頁',
basic: {name: '基礎詳情頁'},
advance: {name: '高級詳情頁'}
},
result: {
name: '結果頁',
success: {name: '成功'},
error: {name: '失敗'}
},
exception: {
name: '異常頁',
404: {name: '404'},
403: {name: '403'},
500: {name: '500'}
},
components: {
name: '小組件',
taskCard: {name: '任務卡片'},
palette: {name: '顏色複選框'}
}
}
}

@ -6,7 +6,6 @@ export default {
isMobile: false,
animates: ADMIN.animates,
palettes: ADMIN.palettes,
routesI18n: {},
dustbins: [],
...config,
},
@ -38,9 +37,6 @@ export default {
setLang(state, lang) {
state.lang = lang
},
setRoutesI18n(state, i18n) {
state.routesI18n = i18n
},
setHideSetting(state, hideSetting) {
state.hideSetting = hideSetting
},

@ -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…
Cancel
Save