diff --git a/src/App.vue b/src/App.vue index e1674d35bbdb08a9af56dafc8a6b1e8b980086db..75f4dcad2309be56dd7d2377377efd8e57d2e059 100644 --- a/src/App.vue +++ b/src/App.vue @@ -7,7 +7,6 @@ diff --git a/src/components/menu/menu.js b/src/components/menu/menu.js index e24b0c23bc88aa6ee83e57a163346f23a0cdf6b5..1a7b06dd9e05d108fcda80e0df6184e9712ce8a8 100644 --- a/src/components/menu/menu.js +++ b/src/components/menu/menu.js @@ -34,6 +34,7 @@ import Menu from 'ant-design-vue/es/menu'; import Icon from 'ant-design-vue/es/icon'; import { getUserInfo } from '@/utils'; +import { mapState } from 'vuex'; const { Item, SubMenu } = Menu; @@ -67,24 +68,21 @@ export default { sOpenKeys: [], cachedOpenKeys: [], menuData: [], + allMenuList: [], }; }, computed: { + ...mapState('settingModule', ['layout']), menuTheme() { return this.theme == 'light' ? this.theme : 'dark'; }, }, created() { const { menuList } = getUserInfo(); + // 增加查询速度 this.menuData = menuList.filter(i => i.menuType === 'MENU'); + this.allMenuList = menuList; this.updateMenu(); - // // 自定义国际化配置 - // if (this.i18n && this.i18n.messages) { - // const messages = this.i18n.messages; - // Object.keys(messages).forEach(key => { - // this.$i18n.mergeLocaleMessage(key, messages[key]); - // }); - // } }, watch: { i18n(val) { @@ -103,9 +101,6 @@ export default { this.sOpenKeys = this.cachedOpenKeys; } }, - $route: function() { - this.updateMenu(); - }, sOpenKeys(val) { this.$emit('openChange', val); this.$emit('update:openKeys', val); @@ -123,17 +118,37 @@ export default { } return !icon || icon == 'none' ? null : h(Icon, { props: { type: icon } }); }, + renderMenuItem(h, menu) { const tag = 'router-link'; + const config = { - props: { to: menu.path }, + props: { to: menu.menuUrl }, attrs: { style: 'overflow:hidden;white-space:normal;text-overflow:clip;' }, }; + // 菜单 + if (menu.menuType === 'MENU') { + return h(Item, { key: menu.menuId }, [ + h(tag, config, [this.renderIcon(h, menu.menuIcon, menu.menuId), menu.menuName]), + ]); + } return h(Item, { key: menu.menuId }, [ - h(tag, config, [this.renderIcon(h, menu.menuIcon, menu.menuId), menu.menuName]), + h( + 'a', + { + attrs: { style: 'overflow:hidden;white-space:normal;text-overflow:clip;' }, + on: { + click(e) { + e.preventDefault(); + }, + }, + }, + [this.renderIcon(h, menu.menuIcon, menu.menuId), menu.menuName], + ), ]); }, + renderSubMenu(h, menu) { const subItem = [ h( @@ -146,52 +161,63 @@ export default { ), ]; const itemArr = []; + menu.children.forEach(item => { itemArr.push(this.renderItem(h, item)); }); + return h(SubMenu, { key: menu.menuId }, subItem.concat(itemArr)); }, + renderItem(h, menu) { return menu.children && menu.children.length ? this.renderSubMenu(h, menu) : this.renderMenuItem(h, menu); }, + renderMenu(h, menuTree) { - let menuArr = []; - menuTree.forEach((menu, i) => { + const menuArr = []; + + menuTree.forEach(menu => { menuArr.push(this.renderItem(h, menu)); }); + return menuArr; }, updateMenu() { - this.selectedKeys = this.getSelectedKey(this.$route); + this.selectedKeys = this.getSelectedKey(); + // 混合模式 不管 + if (this.layout !== 'mix') this.sOpenKeys = this.getOpenKeysByPath(this.$route.path); + }, - // let openKeys = matchedRoutes.map(item => item.path); + getSelectedKey() { + const { path } = this.$route; + let routeToMenu = this.menuData.find(m => m.menuUrl === path); - // openKeys = openKeys.slice(0, openKeys.length - 1); + if (this.layout !== 'mix') return [routeToMenu.menuId]; - // if (!fastEqual(openKeys, this.sOpenKeys)) { - // this.collapsed || this.mode === 'horizontal' - // ? (this.cachedOpenKeys = openKeys) - // : (this.sOpenKeys = openKeys); - // } - this.sOpenKeys = this.getOpenKeysByPath(this.$route.path); - }, - getSelectedKey(route) { - const { path } = route; - return [this.menuData.find(m => m.menuUrl === path).menuId]; + // 说明这是头部菜单 + if (this.mode === 'horizontal') { + let parentMenuId = routeToMenu.parentMenuId; + while (parentMenuId !== 0) { + routeToMenu = this.allMenuList.find(m => m.menuId === parentMenuId); + parentMenuId = routeToMenu.parentMenuId; + } + return [routeToMenu.menuId]; + } + + return []; }, getOpenKeysByPath(path) { - const { menuList } = getUserInfo(); const { parentMenuId } = this.menuData.find(m => m.menuUrl === path); if (parentMenuId === 0) return []; const parentMenus = [parentMenuId]; const res = [parentMenuId]; while (parentMenus.length) { const menuId = parentMenus.pop(); - const parentMenu = menuList.find(m => m.menuId === menuId); + const parentMenu = this.allMenuList.find(m => m.menuId === menuId); if (parentMenu.parentMenuId !== 0) { parentMenus.push(parentMenu.parentMenuId); res.push(parentMenu.parentMenuId); @@ -215,7 +241,7 @@ export default { this.sOpenKeys = val; }, click: obj => { - obj.selectedKeys = [obj.key]; + this.selectedKeys = [obj.key]; this.$emit('select', obj); }, }, diff --git a/src/components/page/PageHeader.vue b/src/components/page/PageHeader.vue index 85dc6d35c85c647f683b233ab67a0c1843881fda..750495dee87b503086b6f32a3e2fdf9189e4b665 100644 --- a/src/components/page/PageHeader.vue +++ b/src/components/page/PageHeader.vue @@ -1,48 +1,19 @@ - - diff --git a/src/main.js b/src/main.js index 7f64ea3a5bfaa69dec77816b2344afefc0751d9d..012ef2ca30db8b94a3e2d2fac4a06ca40bd0e5eb 100644 --- a/src/main.js +++ b/src/main.js @@ -8,7 +8,7 @@ import VueI18n from 'vue-i18n'; import { accountModule, settingModule } from './pages/frame/store'; import App from './App.vue'; import Plugins from './plugins'; -import { loadRoutes, loadGuards, setAppOptions } from './utils/routerUtil'; +import { loadGuards, setAppOptions } from './utils/routerUtil'; import guards from './router/guards'; import { loadResponseInterceptor } from './utils/requestUtil'; import langUtils from '@/utils/langUtils'; @@ -56,8 +56,6 @@ Vue.use(Plugins); //设置应用配置 setAppOptions({ router, store, i18n }); -// 加载路由 -loadRoutes(); // 加载路由守卫 loadGuards(guards, { router, store, i18n, message: Vue.prototype.$message }); diff --git a/src/pages/frame/components/header/LayoutTopHeader.vue b/src/pages/frame/components/header/LayoutTopHeader.vue index d63781fbfda1d58a3e3010df819d9aedfff7e3a5..bc542b961fcea4322a82a4376c2afc20e675faa0 100644 --- a/src/pages/frame/components/header/LayoutTopHeader.vue +++ b/src/pages/frame/components/header/LayoutTopHeader.vue @@ -1,25 +1,38 @@ - diff --git a/src/pages/frame/components/tab/LayoutTabsHeader.vue b/src/pages/frame/components/tab/LayoutTabsHeader.vue index 3da474aaf725cb1409e878213062447d77c9daef..4b6f38433cfcdf20bc141ec1993e03bc43f6ecd1 100644 --- a/src/pages/frame/components/tab/LayoutTabsHeader.vue +++ b/src/pages/frame/components/tab/LayoutTabsHeader.vue @@ -1,49 +1,36 @@ - diff --git a/src/pages/frame/store/settingModule.js b/src/pages/frame/store/settingModule.js index c74b49fa5d96ada888b297f5c40b7d172cc2f28b..691998fa21e1202e802478ab21020036c7a96eb3 100644 --- a/src/pages/frame/store/settingModule.js +++ b/src/pages/frame/store/settingModule.js @@ -42,14 +42,6 @@ export default { return menuItem; }); }, - subMenu(state) { - const { menuData, activatedFirst } = state; - if (menuData.length > 0 && !menuData[0].fullPath) { - formatFullPath(menuData); - } - const current = menuData.find(menu => menu.fullPath === activatedFirst); - return (current && current.children) || []; - }, }, mutations: { setDevice(state, isMobile) { @@ -59,6 +51,7 @@ export default { state.theme = theme; }, setLayout(state, layout) { + console.log(layout); state.layout = layout; }, setMultiPage(state, multiPage) { diff --git a/src/pages/frame/view/template/TabsTemplateView.vue b/src/pages/frame/view/template/TabsTemplateView.vue index f19d7008d8632429a5dd38bfe6c9da7e87ce8a02..630631ee7989e79196078056d1b46b4ad9f0dccd 100644 --- a/src/pages/frame/view/template/TabsTemplateView.vue +++ b/src/pages/frame/view/template/TabsTemplateView.vue @@ -10,15 +10,10 @@ @refresh="refresh" @contextmenu="onContextmenu" /> -
- - - - -
+ + + + @@ -28,7 +23,7 @@ import Contextmenu from '@/components/menu/Contextmenu.vue'; import { mapState, mapMutations } from 'vuex'; import { getI18nKey } from '@/utils/routerUtil'; import AKeepAlive from '@/components/cache/AKeepAlive'; -import LayoutTabsHeader from '../../components/tab/LayoutTabsHeader'; +import LayoutTabsHeader from '../../components/tab/LayoutTabsHeader.vue'; import templateI18n from './i18n'; export default { diff --git a/src/router/config.js b/src/router/config.js index 2e676be6bd92ee37d223019061abafe86256329d..81f30ccfd7d043c6c78b55d1a155b3ff851afbb7 100644 --- a/src/router/config.js +++ b/src/router/config.js @@ -24,7 +24,6 @@ const hasAuthorityRoutes = [ path: '/', component: TabsTemplateView, redirect: '/home', - name: '首页', children: [ { path: 'home', @@ -59,12 +58,6 @@ const hasAuthorityRoutes = [ { path: 'system', name: '系统管理', - meta: { - icon: 'setting', - page: { - cacheAble: true, - }, - }, component: PageTemplateView, children: [ { diff --git a/src/router/guards.js b/src/router/guards.js index 5a9f9f0938ae16cde6028ceef2f8667d04e17c7a..d2b4cd9e3a16b00c107df8ff541baa66d1bf3f5e 100644 --- a/src/router/guards.js +++ b/src/router/guards.js @@ -57,43 +57,11 @@ const authorityGuard = (to, from, next, options) => { if (!hasAuthority(to)) { message.warning(`对不起,您无权访问页面: ${to.fullPath},请联系管理员`); next({ path: '/403' }); - // NProgress.done() } else { next(); } }; -/** - * 混合导航模式下一级菜单跳转重定向 - * @param to - * @param from - * @param next - * @param options - * @returns {*} - */ -const redirectGuard = (to, from, next, options) => { - const { store } = options; - const getFirstChild = routes => { - const route = routes[0]; - if (!route.children || route.children.length === 0) { - return route; - } - return getFirstChild(route.children); - }; - if (store.state.settingModule.layout === 'mix') { - const firstMenu = store.getters['settingModule/firstMenu']; - if (firstMenu.find(item => item.fullPath === to.fullPath)) { - store.commit('settingModule/setActivatedFirst', to.fullPath); - const subMenu = store.getters['settingModule/subMenu']; - if (subMenu.length > 0) { - const redirect = getFirstChild(subMenu); - return next({ path: redirect.fullPath }); - } - } - } - next(); -}; - /** * 进度条结束 * @param to @@ -106,6 +74,6 @@ const progressDone = () => { }; export default { - beforeEach: [progressStart, loginGuard, authorityGuard, redirectGuard], + beforeEach: [progressStart, loginGuard, authorityGuard], afterEach: [progressDone], }; diff --git a/src/router/index.js b/src/router/index.js index ce84d89295ed3f45b860561a4c4c342adf4b47d4..589ff59abed2e3a5199cc214f9c3dd4135e13e2c 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,5 +1,4 @@ import syncConfig from './config'; -import { formatRoutes } from '../utils/routerUtil'; // 不需要登录拦截的路由配置 const loginIgnore = { @@ -22,7 +21,6 @@ const loginIgnore = { */ function initRouter() { const options = syncConfig; - formatRoutes(options.routes); return options; } diff --git a/src/utils/routerUtil.js b/src/utils/routerUtil.js index 39bb7336833217fe38b95d2598ec291f63dee759..5ba7bd258ebfe028713aa4a1c759575f29620e88 100644 --- a/src/utils/routerUtil.js +++ b/src/utils/routerUtil.js @@ -70,29 +70,6 @@ function parseRoutes(routesConfig, routerMap) { return routes; } -/** - * 加载路由 - * @param routesConfig {RouteConfig[]} 路由配置 - */ -function loadRoutes(routesConfig) { - // 应用配置 - const { router, store, i18n } = appOptions; - - routesConfig = store.getters['accountModule/routesConfig']; - - // 提取路由国际化数据 - mergeI18nFromRoutes(i18n, router.options.routes); - - // 初始化Admin后台菜单数据 - const rootRoute = router.options.routes.find(item => item.path === '/'); - - const menuRoutes = rootRoute && rootRoute.children; - - if (menuRoutes) { - store.commit('settingModule/setMenuData', menuRoutes); - } -} - /** * 深度合并路由 * @param target {Route[]} @@ -131,57 +108,6 @@ function deepMergeRoutes(target, source) { return parseRoutesMap(merge); } -/** - * 格式化路由 - * @param routes 路由配置 - */ -function formatRoutes(routes) { - routes.forEach(route => { - const { path } = route; - if (!path.startsWith('/') && path !== '*') { - route.path = '/' + path; - } - }); - formatAuthority(routes); -} - -/** - * 格式化路由的权限配置 - * @param routes 路由 - * @param pAuthorities 父级路由权限配置集合 - */ -function formatAuthority(routes, pAuthorities = []) { - routes.forEach(route => { - const meta = route.meta; - const defaultAuthority = pAuthorities[pAuthorities.length - 1] || { permission: '*' }; - if (meta) { - let authority = {}; - if (!meta.authority) { - authority = defaultAuthority; - } else if (typeof meta.authority === 'string') { - authority.permission = meta.authority; - } else if (typeof meta.authority === 'object') { - authority = meta.authority; - const { role } = authority; - if (typeof role === 'string') { - authority.role = [role]; - } - if (!authority.permission && !authority.role) { - authority = defaultAuthority; - } - } - meta.authority = authority; - } else { - const authority = defaultAuthority; - route.meta = { authority }; - } - route.meta.pAuthorities = pAuthorities; - if (route.children) { - formatAuthority(route.children, [...pAuthorities, route.meta.authority]); - } - }); -} - /** * 从路由 path 解析 i18n key * @param path @@ -213,13 +139,4 @@ function loadGuards(guards, options) { }); } -export { - parseRoutes, - loadRoutes, - formatAuthority, - getI18nKey, - loadGuards, - deepMergeRoutes, - formatRoutes, - setAppOptions, -}; +export { parseRoutes, getI18nKey, loadGuards, deepMergeRoutes, setAppOptions };