diff --git a/src/components/menu/menu.js b/src/components/menu/menu.js index 15d18eb..49ef98f 100644 --- a/src/components/menu/menu.js +++ b/src/components/menu/menu.js @@ -77,7 +77,7 @@ export default { }, created () { this.updateMenu() - if (!this.options[0].fullPath) { + if (this.options.length > 0 && !this.options[0].fullPath) { this.formatOptions(this.options, '') } // 自定义国际化配置 @@ -90,7 +90,7 @@ export default { }, watch: { options(val) { - if (!val[0].fullPath) { + if (val.length > 0 && !val[0].fullPath) { this.formatOptions(this.options, '') } }, @@ -195,18 +195,14 @@ export default { }, updateMenu () { const menuRoutes = this.$route.matched.filter(item => item.path !== '') - const route = menuRoutes.pop() - this.selectedKeys = [this.getSelectedKey(route)] + this.selectedKeys = this.getSelectedKey(this.$route) let openKeys = menuRoutes.map(item => item.path) if (!fastEqual(openKeys, this.sOpenKeys)) { this.collapsed || this.mode === 'horizontal' ? this.cachedOpenKeys = openKeys : this.sOpenKeys = openKeys } }, getSelectedKey (route) { - if (route.meta.invisible && route.parent) { - return this.getSelectedKey(route.parent) - } - return route.path + return route.matched.map(item => item.path) } }, render (h) { diff --git a/src/components/setting/Setting.vue b/src/components/setting/Setting.vue index 93ec7f1..d4bdd4d 100644 --- a/src/components/setting/Setting.vue +++ b/src/components/setting/Setting.vue @@ -26,6 +26,7 @@ > + diff --git a/src/components/setting/i18n.js b/src/components/setting/i18n.js index 03873a7..85fb98d 100644 --- a/src/components/setting/i18n.js +++ b/src/components/setting/i18n.js @@ -12,6 +12,7 @@ module.exports = { title: '导航设置', side: '侧边导航', head: '顶部导航', + mix: '混合导航', content: { title: '内容区域宽度', fluid: '流式', @@ -82,6 +83,7 @@ module.exports = { title: 'Navigation Mode', side: 'Side Menu Layout', head: 'Top Menu Layout', + mix: 'Mix Menu Layout', content: { title: 'Content Width', fluid: 'Fluid', diff --git a/src/layouts/AdminLayout.vue b/src/layouts/AdminLayout.vue index 92a9075..dd197fe 100644 --- a/src/layouts/AdminLayout.vue +++ b/src/layouts/AdminLayout.vue @@ -3,7 +3,7 @@ - +
@@ -12,7 +12,7 @@ - +
@@ -32,7 +32,7 @@ import PageFooter from './footer/PageFooter' import Drawer from '../components/tool/Drawer' import SideMenu from '../components/menu/SideMenu' import Setting from '../components/setting/Setting' -import {mapState, mapMutations} from 'vuex' +import {mapState, mapMutations, mapGetters} from 'vuex' const minHeight = window.innerHeight - 64 - 24 - 122 @@ -46,30 +46,61 @@ export default { showSetting: false } }, + watch: { + $route(val) { + this.setActivated(val) + }, + layout() { + this.setActivated(this.$route) + } + }, computed: { ...mapState('setting', ['isMobile', 'theme', 'layout', 'footerLinks', 'copyright', 'fixedHeader', 'fixedSideBar', 'hideSetting', 'menuData']), + ...mapGetters('setting', ['firstMenu', 'subMenu']), sideMenuWidth() { return this.collapsed ? '80px' : '256px' }, headerStyle() { - let width = (this.fixedHeader && this.layout == 'side' && !this.isMobile) ? `calc(100% - ${this.sideMenuWidth})` : '100%' + let width = (this.fixedHeader && this.layout !== 'head' && !this.isMobile) ? `calc(100% - ${this.sideMenuWidth})` : '100%' let position = this.fixedHeader ? 'fixed' : 'static' let transition = this.fixedHeader ? 'transition: width 0.2s' : '' return `width: ${width}; position: ${position}; ${transition}` + }, + headMenuData() { + const {layout, menuData, firstMenu} = this + return layout === 'mix' ? firstMenu : menuData + }, + sideMenuData() { + const {layout, menuData, subMenu} = this + return layout === 'mix' ? subMenu : menuData } }, methods: { - ...mapMutations('setting', ['correctPageMinHeight']), + ...mapMutations('setting', ['correctPageMinHeight', 'setActivatedFirst']), toggleCollapse () { this.collapsed = !this.collapsed }, onMenuSelect () { this.toggleCollapse() }, + setActivated(route) { + if (this.layout === 'mix') { + let matched = route.matched + matched = matched.slice(0, matched.length - 1) + const {firstMenu} = this + for (let menu of firstMenu) { + if (matched.findIndex(item => item.path === menu.fullPath) !== -1) { + this.setActivatedFirst(menu.fullPath) + break + } + } + } + } }, created() { this.correctPageMinHeight(minHeight - 1) + this.setActivated(this.$route) }, beforeDestroy() { this.correctPageMinHeight(-minHeight + 1) diff --git a/src/layouts/header/AdminHeader.vue b/src/layouts/header/AdminHeader.vue index b320432..a65b0ad 100644 --- a/src/layouts/header/AdminHeader.vue +++ b/src/layouts/header/AdminHeader.vue @@ -6,12 +6,12 @@

{{systemName}}

- -
- + +
+
- + @@ -49,7 +49,8 @@ export default { {key: 'CN', name: '简体中文', alias: '简体'}, {key: 'HK', name: '繁體中文', alias: '繁體'}, {key: 'US', name: 'English', alias: 'English'} - ] + ], + searchActive: false } }, computed: { @@ -63,6 +64,12 @@ export default { langAlias() { let lang = this.langList.find(item => item.key == this.lang) return lang.alias + }, + menuWidth() { + const {layout, searchActive} = this + const headWidth = layout === 'head' ? '1236px' : '100%' + const extraWidth = searchActive ? '564px' : '364px' + return `calc(${headWidth} - ${extraWidth})` } }, methods: { diff --git a/src/layouts/header/HeaderSearch.vue b/src/layouts/header/HeaderSearch.vue index bd408cc..ec4f116 100644 --- a/src/layouts/header/HeaderSearch.vue +++ b/src/layouts/header/HeaderSearch.vue @@ -24,10 +24,12 @@ export default { methods: { enterSearchMode () { this.searchMode = true + this.$emit('active', true) setTimeout(() => this.$refs.input.focus(), 300) }, leaveSearchMode () { this.searchMode = false + setTimeout(() => this.$emit('active', false), 300) } } } diff --git a/src/layouts/header/index.less b/src/layouts/header/index.less index 443f030..ba90761 100644 --- a/src/layouts/header/index.less +++ b/src/layouts/header/index.less @@ -4,6 +4,12 @@ box-shadow: @shadow-down; position: relative; background: @base-bg-color; + .head-menu{ + height: 64px; + line-height: 64px; + vertical-align: middle; + box-shadow: none; + } &.dark{ background: @header-bg-color-dark; color: white; diff --git a/src/router/guards.js b/src/router/guards.js index b8719f9..67de64c 100644 --- a/src/router/guards.js +++ b/src/router/guards.js @@ -38,7 +38,30 @@ const authorityGuard = (to, from, next, options) => { } } +/** + * 混合导航模式下一级菜单跳转重定向 + * @param to + * @param from + * @param next + * @param options + * @returns {*} + */ +const redirectGuard = (to, from, next, options) => { + const {store} = options + if (store.state.setting.layout === 'mix') { + const firstMenu = store.getters['setting/firstMenu'] + if (firstMenu.find(item => item.fullPath === to.fullPath)) { + store.commit('setting/setActivatedFirst', to.fullPath) + const subMenu = store.getters['setting/subMenu'] + if (subMenu.length > 0) { + return next({path: subMenu[0].fullPath}) + } + } + } + next() +} + export default { - beforeEach: [loginGuard, authorityGuard], + beforeEach: [loginGuard, authorityGuard, redirectGuard], afterEach: [] } diff --git a/src/store/modules/setting.js b/src/store/modules/setting.js index 7f0c22b..904c173 100644 --- a/src/store/modules/setting.js +++ b/src/store/modules/setting.js @@ -1,5 +1,6 @@ import config from '@/config' import {ADMIN} from '@/config/default' +import {formatFullPath} from '@/utils/i18n' export default { namespaced: true, state: { @@ -8,8 +9,30 @@ export default { palettes: ADMIN.palettes, pageMinHeight: 0, menuData: [], + activatedFirst: undefined, ...config, }, + getters: { + firstMenu(state) { + const {menuData} = state + if (!menuData[0].fullPath) { + formatFullPath(menuData) + } + return menuData.map(item => { + const menuItem = {...item} + delete menuItem.children + return menuItem + }) + }, + subMenu(state) { + const {menuData, activatedFirst} = state + if (!menuData[0].fullPath) { + formatFullPath(menuData) + } + const current = menuData.find(menu => menu.fullPath === activatedFirst) + return current ? current.children : [] + } + }, mutations: { setDevice (state, isMobile) { state.isMobile = isMobile @@ -49,6 +72,9 @@ export default { }, setAsyncRoutes(state, asyncRoutes) { state.asyncRoutes = asyncRoutes + }, + setActivatedFirst(state, activatedFirst) { + state.activatedFirst = activatedFirst } } } diff --git a/src/utils/i18n.js b/src/utils/i18n.js index 50e3c36..ec64b9f 100644 --- a/src/utils/i18n.js +++ b/src/utils/i18n.js @@ -73,5 +73,6 @@ function mergeI18nFromRoutes(i18n, routes) { export { initI18n, - mergeI18nFromRoutes + mergeI18nFromRoutes, + formatFullPath }