增加动态路由;修改路由权限控制逻辑;

This commit is contained in:
huzhushan 2021-07-26 16:48:43 +08:00
parent 5a315f6fe6
commit 0d36b5c7e5
9 changed files with 146 additions and 95 deletions

View File

@ -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,16 +40,18 @@ export default [
method: 'post',
timeout: 1000,
statusCode: 200,
response: ({body}) => {
response: ({ body }) => {
// 响应内容
return +body.password === 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',
}

View File

@ -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: {
response: ({ query }) => {
// 响应内容
const childs = [
{
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: [
{
name: 'nestPage1',
title: 'page1',
},
{
name: 'nestPage2',
title: 'page2',
},
],
},
{
name: 'test-error-log',
title: '测试错误日志',
},
]
if (query.role === 'admin')
childs.push({
name: 'testNoAuth',
title: '权限页面',
})
return {
code: 200,
message: '获取菜单成功',
data: [
{
url: '/test',
name: 'test',
title: '测试页面',
icon: 'el-icon-location',
children: [
{
url: '/test',
title: '列表',
},
{
url: '/test/auth',
title: '权限页面',
},
{
url: '/test/nest',
title: '二级菜单',
children: [
{
url: '/test/nest',
title: '子菜单',
},
],
},
],
children: childs,
},
],
}
},
},
]

View File

@ -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,
})
}

View File

@ -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),

View File

@ -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 }
}
}
})

View File

@ -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) {

View File

@ -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: [

View File

@ -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'],
},
},
],

View File

@ -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)
}
},
},
}