From 0d36b5c7e5950fc5b1ddf907d62b8b6cfb6c4909 Mon Sep 17 00:00:00 2001 From: huzhushan Date: Mon, 26 Jul 2021 16:48:43 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8A=A8=E6=80=81=E8=B7=AF?= =?UTF-8?q?=E7=94=B1=EF=BC=9B=E4=BF=AE=E6=94=B9=E8=B7=AF=E7=94=B1=E6=9D=83?= =?UTF-8?q?=E9=99=90=E6=8E=A7=E5=88=B6=E9=80=BB=E8=BE=91=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mock/login.js | 28 +++++---- mock/menu.js | 80 ++++++++++++++++++------- src/api/menu.js | 5 +- src/layout/components/Sidebar/Menus.vue | 6 +- src/permission.js | 22 +++---- src/router/index.js | 13 ++-- src/router/modules/home.js | 4 +- src/router/modules/test.js | 14 +---- src/store/modules/menu.js | 69 ++++++++++++++------- 9 files changed, 146 insertions(+), 95 deletions(-) diff --git a/mock/login.js b/mock/login.js index 45e6fc9..b6e2c64 100644 --- a/mock/login.js +++ b/mock/login.js @@ -27,7 +27,7 @@ * @version: * @Date: 2021-04-20 11:06:21 * @LastEditors: huzhushan@126.com - * @LastEditTime: 2021-04-21 12:44:46 + * @LastEditTime: 2021-07-26 13:06:50 * @Author: huzhushan@126.com * @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin @@ -40,19 +40,21 @@ export default [ method: 'post', timeout: 1000, statusCode: 200, - response: ({body}) => { + response: ({ body }) => { // 响应内容 - return +body.password === 123456 ? { - code: 200, - message: '登录成功', - data: { - token: '@word(50, 100)', // @word()是mockjs的语法 - refresh_token: '@word(50, 100)', // refresh_token是用来重新生成token的 - } - } : { - code: 400, - message: '密码错误,请输入123456', - } + return +body.password === 123456 + ? { + code: 200, + message: '登录成功', + data: { + token: '@word(50, 100)', // @word()是mockjs的语法 + refresh_token: '@word(50, 100)', // refresh_token是用来重新生成token的 + }, + } + : { + code: 400, + message: '密码错误,请输入123456', + } }, }, { diff --git a/mock/menu.js b/mock/menu.js index fb4366b..d21031e 100644 --- a/mock/menu.js +++ b/mock/menu.js @@ -24,7 +24,7 @@ * @version: * @Date: 2021-04-20 11:06:21 * @LastEditors: huzhushan@126.com - * @LastEditTime: 2021-04-21 12:44:55 + * @LastEditTime: 2021-07-26 16:43:22 * @Author: huzhushan@126.com * @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin @@ -36,36 +36,70 @@ export default [ url: '/api/menus', method: 'get', timeout: 100, - response: { - code: 200, - message: '获取菜单成功', - data: [ + response: ({ query }) => { + // 响应内容 + const childs = [ { - url: '/test', - title: '测试页面', - icon: 'el-icon-location', + name: 'testList', + title: '列表', + }, + { + name: 'testAdd', + title: '添加', + }, + { + name: 'testEdit', + title: '编辑', + }, + { + name: 'testAuth', + title: '权限测试', + }, + { + name: 'test-cache', + title: '该页面可缓存', + }, + { + name: 'test-no-cache', + title: '该页面不可缓存', + }, + { + name: 'nest', + title: '二级菜单', children: [ { - url: '/test', - title: '列表', + name: 'nestPage1', + title: 'page1', }, { - url: '/test/auth', - title: '权限页面', - }, - { - url: '/test/nest', - title: '二级菜单', - children: [ - { - url: '/test/nest', - title: '子菜单', - }, - ], + name: 'nestPage2', + title: 'page2', }, ], }, - ], + { + name: 'test-error-log', + title: '测试错误日志', + }, + ] + + if (query.role === 'admin') + childs.push({ + name: 'testNoAuth', + title: '权限页面', + }) + + return { + code: 200, + message: '获取菜单成功', + data: [ + { + name: 'test', + title: '测试页面', + children: childs, + }, + ], + } }, }, ] diff --git a/src/api/menu.js b/src/api/menu.js index 6845127..a851f93 100644 --- a/src/api/menu.js +++ b/src/api/menu.js @@ -3,7 +3,7 @@ * @version: * @Date: 2021-04-20 11:06:21 * @LastEditors: huzhushan@126.com - * @LastEditTime: 2021-04-21 09:36:57 + * @LastEditTime: 2021-07-26 13:37:30 * @Author: huzhushan@126.com * @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin @@ -12,9 +12,10 @@ import request from '@/utils/request' // 获取菜单 -export const GetMenus = () => { +export const GetMenus = params => { return request({ url: '/api/menus', method: 'get', + params, }) } diff --git a/src/layout/components/Sidebar/Menus.vue b/src/layout/components/Sidebar/Menus.vue index 1d01a32..089fd03 100644 --- a/src/layout/components/Sidebar/Menus.vue +++ b/src/layout/components/Sidebar/Menus.vue @@ -27,7 +27,7 @@ * @version: * @Date: 2021-04-20 11:06:21 * @LastEditors: huzhushan@126.com - * @LastEditTime: 2021-07-23 11:07:24 + * @LastEditTime: 2021-07-26 16:02:28 * @Author: huzhushan@126.com * @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin @@ -75,10 +75,6 @@ export default defineComponent({ setup() { const route = useRoute() const store = useStore() - store.dispatch( - 'menu/generateMenus', - store.state.account.userinfo && store.state.account.userinfo.role - ) return { menus: computed(() => store.state.menu.menus), diff --git a/src/permission.js b/src/permission.js index 4dc5a40..ac1dae3 100644 --- a/src/permission.js +++ b/src/permission.js @@ -26,7 +26,7 @@ * @version: * @Date: 2021-04-20 11:06:21 * @LastEditors: huzhushan@126.com - * @LastEditTime: 2021-05-06 09:21:41 + * @LastEditTime: 2021-07-26 16:32:34 * @Author: huzhushan@126.com * @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin @@ -46,7 +46,7 @@ const getPageTitle = title => { } // 白名单,里面是路由对象的name -const WhiteList = ['login', 'forbidden', 'server-error', 'not-found', 'lock'] +const WhiteList = ['login', 'lock'] // vue-router4的路由守卫不再是通过next放行,而是通过return返回true或false或者一个路由地址 router.beforeEach(async to => { @@ -74,6 +74,15 @@ router.beforeEach(async to => { return false } } + // 获取动态菜单(如果你的项目有动态菜单,在此处获取动态菜单) + if (store.state.menu.menus.length <= 0) { + try { + await store.dispatch('menu/generateMenus', userinfo) + return to.fullPath // 添加动态路由后,必须加这一句触发重定向 + } catch (err) { + return false + } + } // 判断是否处于锁屏状态 if (to.name !== 'lock') { @@ -88,14 +97,5 @@ router.beforeEach(async to => { } } } - - // 如果没有权限,跳转到403页面 - if ( - !!to.meta && - !!to.meta.roles && - !to.meta.roles.includes(userinfo.role) - ) { - return { path: '/403', replace: true } - } } }) diff --git a/src/router/index.js b/src/router/index.js index b30ace8..4664981 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -18,7 +18,7 @@ * @version: * @Date: 2021-04-20 11:06:21 * @LastEditors: huzhushan@126.com - * @LastEditTime: 2021-04-23 15:26:46 + * @LastEditTime: 2021-07-26 16:16:36 * @Author: huzhushan@126.com * @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin @@ -34,8 +34,11 @@ import lock from './modules/lock' import home from './modules/home' import test from './modules/test' -// 左侧菜单 -export const allMenus = [...home, ...test] +/* 菜单栏的路由 */ +// 固定菜单 +export const fixedRoutes = [...home] +// 动态菜单 +export const asyncRoutes = [...test] const router = createRouter({ history: createWebHashHistory(), @@ -46,9 +49,9 @@ const router = createRouter({ }, ...redirect, // 统一的重定向配置 ...login, - ...allMenus, - ...error, ...lock, + ...fixedRoutes, + ...error, ], scrollBehavior(to, from, savedPosition) { if (savedPosition) { diff --git a/src/router/modules/home.js b/src/router/modules/home.js index 1ae198d..a7d434e 100644 --- a/src/router/modules/home.js +++ b/src/router/modules/home.js @@ -3,7 +3,7 @@ * @version: * @Date: 2021-04-20 11:06:21 * @LastEditors: huzhushan@126.com - * @LastEditTime: 2021-04-21 09:34:35 + * @LastEditTime: 2021-07-26 14:37:08 * @Author: huzhushan@126.com * @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin @@ -19,7 +19,7 @@ export default [ component: Layout, name: 'Dashboard', meta: { - title: 'Dashboard', + title: '工作台', }, icon: 'home', children: [ diff --git a/src/router/modules/test.js b/src/router/modules/test.js index 60ce8e0..922b73b 100644 --- a/src/router/modules/test.js +++ b/src/router/modules/test.js @@ -3,7 +3,7 @@ * @version: * @Date: 2021-04-21 09:18:32 * @LastEditors: huzhushan@126.com - * @LastEditTime: 2021-04-29 11:20:14 + * @LastEditTime: 2021-07-26 16:30:58 * @Author: huzhushan@126.com * @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin @@ -31,7 +31,6 @@ export default [ title: '测试页面', }, icon: 'el-icon-location', - roles: ['admin', 'visitor'], children: [ { path: '', @@ -39,7 +38,6 @@ export default [ component: List, meta: { title: '列表', - roles: ['admin', 'visitor'], }, }, { @@ -48,7 +46,6 @@ export default [ component: Add, meta: { title: '添加', - roles: ['admin', 'visitor'], }, hidden: true, // 不在菜单中显示 }, @@ -58,7 +55,6 @@ export default [ component: Edit, meta: { title: '编辑', - roles: ['admin', 'visitor'], }, hidden: true, // 不在菜单中显示 }, @@ -68,7 +64,6 @@ export default [ component: Auth, meta: { title: '权限测试', - roles: ['admin', 'visitor'], }, }, { @@ -77,7 +72,6 @@ export default [ component: NoAuth, meta: { title: '权限页面', - roles: ['admin'], }, hidden: true, }, @@ -87,7 +81,6 @@ export default [ component: Iscache, meta: { title: '该页面可缓存', - roles: ['admin', 'visitor'], }, }, { @@ -96,7 +89,6 @@ export default [ component: Nocache, meta: { title: '该页面不缓存', - roles: ['admin', 'visitor'], noCache: true, // 不缓存页面 }, }, @@ -107,7 +99,6 @@ export default [ redirect: '/test/nest/page1', meta: { title: '二级菜单', - roles: ['admin', 'visitor'], }, children: [ { @@ -116,7 +107,6 @@ export default [ component: NestPage1, meta: { title: 'page1', - roles: ['admin', 'visitor'], }, }, { @@ -125,7 +115,6 @@ export default [ component: NestPage2, meta: { title: 'page2', - roles: ['admin', 'visitor'], }, }, ], @@ -136,7 +125,6 @@ export default [ component: ErrorLog, meta: { title: '测试错误日志', - roles: ['admin', 'visitor'], }, }, ], diff --git a/src/store/modules/menu.js b/src/store/modules/menu.js index 830e8ff..6ea233f 100644 --- a/src/store/modules/menu.js +++ b/src/store/modules/menu.js @@ -3,21 +3,22 @@ * @version: * @Date: 2021-04-20 11:06:21 * @LastEditors: huzhushan@126.com - * @LastEditTime: 2021-04-21 09:34:17 + * @LastEditTime: 2021-07-26 16:11:08 * @Author: huzhushan@126.com * @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin * @Donate: https://huzhushan.gitee.io/vue3-element-admin/donate/ */ -import { allMenus } from '@/router' -// import { GetMenus } from '@/api/menu'; +import { fixedRoutes, asyncRoutes } from '@/router' +import { GetMenus } from '@/api/menu' +import router from '@/router' -const hasPermission = (role, route) => { - if (!!route.meta && !!route.meta.roles && !route.meta.roles.includes(role)) { - return false - } - return true -} +// const hasPermission = (role, route) => { +// if (!!route.meta && !!route.meta.roles && !route.meta.roles.includes(role)) { +// return false +// } +// return true +// } const generateUrl = (path, parentPath) => { return path.startsWith('/') @@ -27,11 +28,34 @@ const generateUrl = (path, parentPath) => { : parentPath } -const getFilterMenus = (arr, role, parentPath = '') => { +const getFilterRoutes = (targetRoutes, ajaxRoutes) => { + const filterRoutes = [] + + ajaxRoutes.forEach(item => { + const target = targetRoutes.find(target => target.name === item.name) + + if (target) { + const { children: targetChildren, ...rest } = target + const route = { + ...rest, + } + + if (item.children) { + route.children = getFilterRoutes(targetChildren, item.children) + } + + filterRoutes.push(route) + } + }) + + return filterRoutes +} + +const getFilterMenus = (arr, parentPath = '') => { const menus = [] arr.forEach(item => { - if (hasPermission(role, item) && !item.hidden) { + if (!item.hidden) { const menu = { url: generateUrl(item.path, parentPath), title: item.meta.title, @@ -41,7 +65,7 @@ const getFilterMenus = (arr, role, parentPath = '') => { if (item.children.filter(child => !child.hidden).length <= 1) { menu.url = generateUrl(item.children[0].path, menu.url) } else { - menu.children = getFilterMenus(item.children, role, menu.url) + menu.children = getFilterMenus(item.children, menu.url) } } menus.push(menu) @@ -62,16 +86,19 @@ export default { }, }, actions: { - async generateMenus({ commit }, role) { - // 方式一:根据角色生成菜单 - const menus = getFilterMenus(allMenus, role) - commit('SET_MENUS', menus) + async generateMenus({ commit }, userinfo) { + // 从后台获取菜单 + const { code, data } = await GetMenus({ role: userinfo.role }) - // // 方式二:从后台获取菜单 - // const { code, data } = await GetMenus(); - // if (+code === 200) { - // commit('SET_MENUS', data) - // } + if (+code === 200) { + // 过滤出需要添加的动态路由 + const filterRoutes = getFilterRoutes(asyncRoutes, data) + filterRoutes.forEach(route => router.addRoute(route)) + + // 生成菜单 + const menus = getFilterMenus([...fixedRoutes, ...filterRoutes]) + commit('SET_MENUS', menus) + } }, }, }