From 0b042bcf6a5406b215da5966092cbd9879ef1d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B0=B4=E8=90=BD=28YangLei=29?= Date: Wed, 7 Jul 2021 10:57:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=8F=9C=E5=8D=95=E6=9D=83=E9=99=90?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 9 +- src/components/menu/SideMenu.vue | 9 +- src/components/menu/menu.js | 86 +++++++----- src/components/page/PageHeader.vue | 39 +----- src/main.js | 4 +- .../components/header/LayoutTopHeader.vue | 49 ++++--- .../components/header/LayoutTopHeaderLang.vue | 4 +- .../frame/components/setting/Setting.vue | 8 +- .../frame/components/setting/SettingItem.vue | 20 +-- .../frame/components/tab/LayoutTabsHeader.vue | 124 +++++------------- src/pages/frame/layouts/AdminLayout.vue | 78 +++++++---- src/pages/frame/layouts/CommonLayout.vue | 13 +- src/pages/frame/layouts/PageLayout.vue | 62 +++------ src/pages/frame/store/settingModule.js | 9 +- .../frame/view/template/TabsTemplateView.vue | 15 +-- src/router/config.js | 7 - src/router/guards.js | 34 +---- src/router/index.js | 2 - src/utils/routerUtil.js | 85 +----------- 19 files changed, 223 insertions(+), 434 deletions(-) diff --git a/src/App.vue b/src/App.vue index e1674d3..75f4dca 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 e24b0c2..1a7b06d 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 85dc6d3..750495d 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 7f64ea3..012ef2c 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 d63781f..bc542b9 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 3da474a..4b6f384 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 c74b49f..691998f 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 f19d700..630631e 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 2e676be..81f30cc 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 5a9f9f0..d2b4cd9 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 ce84d89..589ff59 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 39bb733..5ba7bd2 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 }; -- GitLab