[学习笔记]vue利用动态路由实现菜单权限管理

b站很多实战教程,尤其是后台管理系统的教程基本上只教了些皮毛,很多实用性强的功能基本上没有说,这也是我遇到这种问题无从下手的原因,这里推荐一个教程,也是b站上可看。https://www.bilibili.com/video/BV1zJ411g7Fx 不敢说他教的有多好,但是他的教学内容很接近实际开发了,其中就包含了动态路由。

前期很迷茫,看了许许多多的博客帖子,基本上所有的教程都围绕这一页面https://juejin.im/post/6844903478880370701,我的思路基本上就是照着这个来的。

首先写好静态和动态的路由(并非最终路由,仅供参考用)

export const constantRouterMap = [{ //静态路由
        path: '/',
        redirect: '/login'
    },
    {
        path: '/login',
        component: Login
    },

]

export const asyncRouterMap = [{ //动态路由
    name: 'home',
    path: '/home',
    component: Home,
    meta: {
        title: '首页',
        roles: ['admin', 'editor', 'list']
    },
    children: [{
            name: 'user',
            path: '/user', 
            key: '1',
            components: User,
            meta: {
                title: '用户',
                roles: ['admin', 'editor']
            }
        },
        {
            name: 'shop',
            path: '/shop',
            key: '2',
            components: Shop,
            meta: {
                title: '商品',
                roles: ['admin', 'editor', 'list']
            }
        },
        {
            name: 'rights',
            path: '/rights',
            key: '3',
            components: Rights,
            meta: {
                title: '权限',
                roles: ['admin', 'editor']
            }
        },
        {
            name: 'operate',
            path: '/operate',
            key: '4',
            components: Operate,
            meta: {
                title: '设置',
                roles: ['admin']
            }
        },
    ]
}, {
    path: '*',
    component: NotFound
}]

const router = new VueRouter({
    routes: constantRouterMap,
})

export default router

之后设置路由导航守卫

router.beforeEach((to, from, next) => {
    if (getToken()) {  //获取token
        if (to.path === '/login') {
            store.state.userinfo = [] //调试用,在登录页清空用户数据
            store.state.addRouters = []
            sessionStorage.clear()
            next()
        } else {
            if (sessionStorage.getItem('roles')) { //有角色信息,可直接跳转
                next()
            } else {
                axios({  //没有角色信息,根据用户token获取角色
                    method: "post",
                    url: "/userrole",
                    data: {
                        token: sessionStorage.getItem('token')
                    }
                }).then(data => { 
                    const userRole = data.data //保存用户角色
                    store.dispatch('GenerateRoutes', userRole).then(() => { //根据用户角色生成路由
                        const newRouter = store.state.addRouters
                        router.addRoutes(newRouter)  //添加路由
                        sessionStorage.setItem('roles', userRole) //将角色添加至session中
                        sessionStorage.setItem('router', JSON.stringify(store.state.routers))
                        next({...to, replace: true })
                    }).catch(
                        (err) => {
                            if (err) {
                                Message.error('网络错误,请重试')
                                setTimeout(() => {
                                    sessionStorage.removeItem('roles')
                                    setTimeout(() => {
                                        location.reload()
                                    }, 0)
                                    NProgress.done()
                                }, 2000)
                            }
                        }
                    )
                });

            }
        }
    } else {
        if (whiteList.indexOf(to.path) !== -1) {
            next()
        } else {
            next('/login')
        }
    }
})

GenerateRoutes:

GenerateRoutes({ commit }, data) {
            return new Promise(resolve => {
                const roles = data //保存传入的角色
                let accessedRouters //设置临时路由
                if (roles.includes('admin') === true) {
                    accessedRouters = asyncRouterMap //管理员赋予所有权限
                } else {
                    accessedRouters = filterAsyncRouter(asyncRouterMap, roles) //非管理员筛选权限
                }
                commit('SET_ROUTERS', accessedRouters)
                resolve()
            })
        }

filterAsyncRouter和hasPermission:

function filterAsyncRouter(asyncRouterMap, roles) { //传入两个参数,路由和角色
    const accessedRouters = asyncRouterMap.filter(route => {
        if (hasPermission(roles, route)) { //若得到true,执行下一步
            if (route.children && route.children.length) { //判断是否存在子路由
                route.children = filterAsyncRouter(route.children, roles) //对子路由进行过滤
            }
            return true
        }
        return false
    })
    return accessedRouters
}

function hasPermission(roles, route) {
    if (route.meta && route.meta.roles) { //需要角色的路由
        return roles.some(role => route.meta.roles.includes(role) === true) //存在该角色,返回true,否则返回false
    } else {
        return true
    }
}

SET_ROUTERS:

SET_ROUTERS: (state, routers) => {
            state.addRouters = routers //将筛选后的权限添加到addRouters内
            state.routers = constantRouterMap.concat(routers) //最终路由为默认路由+筛选后的路由
        }

admin界面:

editor界面:

list界面:

猜你喜欢

转载自blog.csdn.net/iufesjgc/article/details/108753372