vue后台管理权限控制

说到后台管理系统,就免不了涉及到权限的管理。在项目中,主要遇到的有两种,一种是页面的限制,一种操作按钮的限制。

首先我们聊一下页面的权限限制:

一、路由的配置 (router—> index.js)

1、不对权限做限制的页面(路由的初始配置)

export const constantRouterMap = [
    {
        path: '/',
        name: 'Login',
        component: Login
    },
    { path: '/404', component: () => import('@/views/errorPage/404'), hidden: true },
    { path: '/401', component: () => import('@/views/errorPage/401'), hidden: true },
]


export default new Router({
    // mode: 'history', // 路由开启history模式时,需要进行服务器配置,vue官网有介绍
    scrollBehavior: () => ({ y: 0 }),
    routes: constantRouterMap
})

2、需要根据不同权限生成不同的路由列表

export const asyncRouterMap = [
    {
        path: '/home',
        name: 'home',
        component: Home,
        redirect: {
            name: "index"
        },
        meta: {
            roles: [0, 1, 2],
            isLogin: true
        },
        children: [
            {
                path: 'index',
                name: 'index',
                component: Index,
                meta: {
                    roles: [0, 1, 2]
                }
            },
            {
                path: 'client',
                name: 'client',
                component: Client,
                meta: {
                    roles: [0, 1, 2]
                }
            },
            {
                path: 'resource',
                name: 'resource',
                component: Resoure,
                meta: {
                    roles: [0, 1, 2]
                }
            },
            {
                path: 'recommend',
                name: 'recommend',
                component: Recommend,
                meta: {
                    roles: [0, 1, 2]
                }
            },
            {
                path: 'setting/hunter',
                name: 'hunter',
                component: Hunter,
                meta: {
                    roles: [0, 1, 2]
                }
            },
            {
                path: 'setting/handover',
                name: 'handover',
                component: handOver,
                meta: {
                    roles: [0, 1, 2]
                }
            },
            {
                path: 'setting/analysis',
                name: 'analysis',
                component: analysis,
                meta: {
                    roles: [0, 1, 2]
                }
            },
            {
                path: 'setting/department',
                name: 'department',
                component: departmentSetting,
                meta: {
                    roles: [0]
                }
            },
            {
                path: 'setting/employer',
                name: 'employer_setting',
                component: employerSetting,
                meta: {
                    roles: [0]
                }
            },
            { path: '*', redirect: '/404', hidden: true } // 404配置需放到路由配置最后,当 
                                                          // 用户访问没有权限的时候,则会跳 
                                                          // 转到404页
        ]
    }
]

二、公用方法的提取

// 判断是否有权限方法
export function hasPermission(roles, route) {
    if (route.meta && route.meta.roles) {
        return roles.some(role => route.meta.roles.indexOf(role) >= 0)
    } else {
        return true
    }
}
//根据角色、过滤出路由列表
export function filterAsyncRouter(asyncRouterMap, roles) {
    const accessedRouters = asyncRouterMap.filter(route => {
        if (hasPermission(roles, route)) {
            if (route.children && route.children.length) {
                route.children = filterAsyncRouter(route.children, roles)
            }
            return true
        }
        return false
    })
    return accessedRouters
}

三、通过vuex管理一些变量

import Vue from 'vue'
import Vuex from 'vuex'
import { asyncRouterMap, constantRouterMap } from '@/router'
import { filterAsyncRouter } from '@/assets/js/common.js'
Vue.use(Vuex)
export default new Vuex.Store({
    state: {
        routers: constantRouterMap, // 最终的路由列表
        addRouters: [], // 根据权限得到的路由列表
        roles: [] // 角色列表,可能一个用户名,存在多个角色,所以用数组的形式
    },
    mutations: {
        SET_ROLES: (state, roles) => {
            state.roles = roles
        },
        SET_ROUTERS: (state, routers) => {
            state.addRouters = routers
            state.routers = constantRouterMap.concat(routers)
        }
    },
    actions: {
        GenerateRoutes({ commit }, data) {
            // 当前登录账号的角色数组
            return new Promise(resolve => {
                const { roles } = data
                let accessedRouters
                // 如果当前账号级别为0,则拥有所有的权限
                if (roles.indexOf(0) >= 0) {
                    accessedRouters = asyncRouterMap
                } else {
                    // 过滤账户权限
                    accessedRouters = filterAsyncRouter(asyncRouterMap, roles)

                }
                commit('SET_ROUTERS', accessedRouters)
                resolve()
            })
        }
    }

})

四、登录操作

this.$http.post("/user/login", qs.stringify(this.loginForm)).then(res => {
    if (res.data.code === 200) {
        cookie.set("userInfo", res.data.data);
        this.$router.push({
            name: "home"
        });
    }
});

补充说明:

1、axios默认的数据格式为json,如果后台接口接收的数据格式不是json,则需要通过qs进行序列化处理

2、cookie 、 js为依赖,使用时,请下载以及引入

五、permission.js

import router from './router'
import store from './store'
import { hasPermission } from '@/assets/js/common.js'
import cookie from 'js-cookie'
// 不需要登录就可以访问的页面
const whiteList = ['/', '/404', '/401']
router.beforeEach((to, from, next) => {
    const shiroCookie = cookie.get('userInfo')
    if (shiroCookie) {
        if (store.state.roles.length === 0) {
            // 登录操作后,以及当刷新页面是store中的数据恢复到初始值,需要重新设置
            const roles = [JSON.parse(cookie.get("userInfo")).position]
            store.commit('SET_ROLES', roles)
            store.dispatch('GenerateRoutes', { roles }).then(() => { // 根据roles权限生成可访问的路由表
                router.addRoutes(store.state.addRouters) // 动态添加可访问路由表
                next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
            })
        } else {
            // 没有刷新页面对路由权限验证
            if (to.meta.roles && to.meta.roles.length) {
                // 当前路由有权限限制时,经过验证后,允许跳转
                if (hasPermission(store.state.roles, to.meta.roles)) {
                    next()
                }
            } else {
                // 不存在权限限制时,则允许跳转
                next()
            }
        }
    } else {
        if (whiteList.indexOf(to.path) !== -1) {
            // 如果在白名单之列,则允许跳转
            next()
        } else {
            // 如果不在白名单之列,则返回登录页
            next('/')
        }
    }
})

最后在main.js中引入该文件就可以

 

最后我们可以通过指令来实现操作按钮的权限控制,以及导航栏的渲染。导航栏部分,我们也可以通过配置路由信息,根据store.state.addRouters的值来动态生成。

六、当进行退出操作时的操作

this.$http.post("/user/logout").then(res => {
    if (res.data.code === 200) {
        cookie.remove("userInfo");
        this.$store.commit('SET_ROLES', [])
        this.$router.push({
            name: "Login"
        });
    }
});

 

你可能感兴趣的:(Vue2+)