vue-element-admin权限控制路由数据关系分析

104 阅读2分钟

权限控制的主体思路:

前端会有一份路由表,它表示了每一个路由可访问的权限。当用户登录之后,通过 token 获取用户的 role ,动态根据用户的 role 算出其对应有权限的路由,再通过router.addRoutes动态挂载路由。

路由数据关系分析:

角色roles为editor,从后台获取的平型路由数据格式:

const HouTaiRoutes = [
    {
        path: "/dashboard",
        name: "Dashboard",
        meta: {
            title: "首页",
            icon: "dashboard",
            roles: [
                "editor"
            ]
        }
    },
    {
        path: "/personal",
        name: "Personal",
        meta: {
            title: "个人中心",
            icon: "el-icon-s-help",
            roles: [
                "editor"
            ]
        }
    },
    {
        path: "/article",
        name: "Article",
        meta: {
            title: "文章管理",
            icon: "el-icon-s-help",
            roles: [
                "editor"
            ]
        }
    },
    {
        path: "create",
        name: "CreateArticle",
        meta: {
            title: "创建文章",
            icon: null,
            roles: [
                "editor"
            ]
        }
    },
    {
        path: "edit/:id(\\d+)",
        name: "EditArticle",
        meta: {
            title: "编辑文章",
            icon: null,
            roles: [
                "editor"
            ]
        }
    },
    {
        path: "list",
        name: "ArticleList",
        meta: {
            title: "文章列表",
            icon: null,
            roles: [
                "editor"
            ]
        }
    },
    {
        path: '*',
        redirect: '/404',
        hidden: true
    }

]

前端已保存的异步路由数据格式:

const HaveRoutes = [
    {
        path: "/dashboard",
        name: "Dashboard",
        meta: {
            title: "首页",
            icon: "dashboard",
            roles: [

            ]
        }
    },
    {
        path: "/personal",
        name: "Personal",
        meta: {
            title: "个人中心",
            icon: "el-icon-s-help",
            roles: [

            ]
        }
    },
    {
        path: "/article",
        name: "Article",
        meta: {
            title: "文章管理",
            icon: "el-icon-s-help",
            roles: [

            ]
        },
        children: [
            {
                path: "create",
                name: "CreateArticle",
                meta: {
                    title: "创建文章",
                    icon: null,
                    roles: [

                    ]
                }
            },
            {
                path: "edit/:id(\\d+)",
                name: "EditArticle",
                meta: {
                    title: "编辑文章",
                    icon: null,
                    roles: [

                    ]
                }
            },
            {
                path: "list",
                name: "ArticleList",
                meta: {
                    title: "文章列表",
                    icon: null,
                    roles: [

                    ]
                }
            },
        ]
    },
    {
        path: '/account',
        name: 'Account',
        meta: {
            title: '账户管理',
            icon: 'user',
            roles: []
        },
        children: [
            {
                path: 'add_account',
                name: 'AddAccount',
                meta: { title: '添加账户' }
            },
            {
                path: 'manage_account',
                name: 'ManageAccount',
                meta: { title: '账户列表' }
            }
        ]
    },
    {
        path: '*',
        redirect: '/404',
        hidden: true
    }

]

想要的路由数据格式:

const wantedRoutes = [
    {
        "path": "/dashboard",
        "name": "Dashboard",
        "meta": {
            "title": "首页",
            "icon": "dashboard",
            "roles": [
                "editor"
            ]
        }
    },
    {
        "path": "/personal",
        "name": "Personal",
        "meta": {
            "title": "个人中心",
            "icon": "el-icon-s-help",
            "roles": [
                "editor"
            ]
        }
    },
    {
        "path": "/article",
        "name": "Article",
        "meta": {
            "title": "文章管理",
            "icon": "el-icon-s-help",
            "roles": [
                "editor"
            ]
        },
        children: [
            {
                "path": "create",
                "name": "CreateArticle",
                "meta": {
                    "title": "创建文章",
                    "icon": null,
                    "roles": [
                        "editor"
                    ]
                }
            },
            {
                "path": "edit/:id(\\d+)",
                "name": "EditArticle",
                "meta": {
                    "title": "编辑文章",
                    "icon": null,
                    "roles": [
                        "editor"
                    ]
                }
            },
            {
                "path": "list",
                "name": "ArticleList",
                "meta": {
                    "title": "文章列表",
                    "icon": null,
                    "roles": [
                        "editor"
                    ]
                }
            },
        ]
    },
    {
        "path": "*",
        "redirect": "/404",
        "hidden": true
    }
]

大体实现的思路分为两步:

1,根据后台返回的路由数据为已有的路由数据roles字段添加角色信息

抽象为平级数据转换为树状数据,需用到递归

function makePermisson(HouTaiRoutes, HaveRoutes) {
    HaveRoutes.map((item) => {
        if (!('name' in item))
            return
        HouTaiRoutes.forEach(ele => {
            if (ele.name === item.name)
                item.meta.roles = ele.meta.roles
        });
        if (item.children)
            makePermisson(HouTaiRoutes, item.children)
    })
    return HaveRoutes
}

2,删除没有roles字段或者roles字段为空的路由数据

function filterRoutes(permissionRoutes, roles) {
    console.log(roles);
    const acessRoutes = permissionRoutes.filter(ele => {
        if (!ele.meta || !ele.meta.roles) return
        console.log(ele.meta.roles.includes(roles));
        return ele.meta.roles.includes(roles)
    });
    return acessRoutes
}