权限相关

147 阅读2分钟

权限相关

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)
    /**
     * routes中设置基础路由
     * asyncRoutes中设置需要根据角色权限动态加载的页面路由
     */
export const routes = [{
        path: '/',
        name: 'Home',
        component: () =>
            import ('../views/Home.vue'),
    },
    {
        path: '/login',
        name: 'login',
        component: () =>
            import ('../views/Login.vue'),
        hidden: true, // 为true时在页面导航中隐藏
    },
    {
        path: '/404',
        name: '404',
        component: () =>
            import ('../views/404.vue'),
        hidden: true, // 为true时在页面导航中隐藏
    }
]

export const asyncRoutes = [{
        path: '/page1',
        name: 'Page1',
        component: () =>
            import ('../views/RolePage1.vue'),
        meta: { roles: ['super', 'admin'] }
    },
    {
        path: '/page2',
        name: 'Page2',
        component: () =>
            import ('../views/RolePage2.vue'),
        meta: { roles: ['super', 'kefu'] }
    },
    {
        path: '/page3',
        name: 'Page3',
        component: () =>
            import ('../views/RolePage3.vue'),
        meta: { roles: ['kefu'] }
    },
    { path: '*', redirect: '/404', hidden: true }
]


export default new VueRouter({
    routes
})

store/modules/user.js

import { TOKEN, USER_INFO } from '../../config/mockData'
const user = {
    state: {
        username: "",
        roles: [],
    },
    mutations: {
        SET_USER(state, data) {
            state.username = data.username
            state.roles = data.roles
        }
    },
    actions: {
        /**
         * 模拟登录
         */
        async login() {
            localStorage.JWT_TOKEN = TOKEN
            return TOKEN
        },
        /**
         * 模拟获取用户信息 
         */
        async getUser({ commit }) {
            let userInfo = USER_INFO
            commit('SET_USER', userInfo) // 吧info放到全局 其他地方的js 方便调用即可
            return userInfo
        }
    }
}
export default user

store/modules/permission.js

import { routes, asyncRoutes } from '../../router/index.js'

/**
 * 通过meta中的roles信息判断用户是否有权限   核心就是改这一段即可
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
    if (route.meta && route.meta.roles) {
        return roles.some(role => route.meta.roles.includes(role))
    } else {
        return true
    }
}

/**
 * 根据角色和配置生成当前用户的路由
 * @param {array} routes 配置的路由
 * @param {array} roles 用户角色
 */
let GenerateRoutes = (routes, roles) => {
    let res = []
    routes.forEach(route => {
        const tmp = {...route }
        if (hasPermission(roles, tmp)) { // 匹配到了就添加到res 中
            if (tmp.children) {
                tmp.children = GenerateRoutes(tmp.children, roles)
            }
            res.push(tmp)
        }
    })
    return res
}





const permission = {
    state: {
        roles: [],
        routes: routes // 用于配置页面导航等
    },
    mutations: {
        SET_ROLES: (state, roles) => {
            state.roles = roles
        },
        SET_ROUTES: (state, routes) => {
            state.routes = routes
        }
    },
    actions: {
        /**根据角色获取路由配置 */
        getAsyncRoutes({ commit }, roles) {
            commit('SET_ROLES', roles) // 保存roles信息到store中
            let filterRoutes = GenerateRoutes(asyncRoutes, roles)
            let res = routes.concat(filterRoutes)
            commit('SET_ROUTES', res)
            return res
        }
    }
}
export default permission

src/permission.js

import router from './router'
import store from './store'

const whiteList = ['/login', '/404'] // 免登录白名单

router.beforeEach(async(to, from, next) => {
    let token = localStorage.getItem('JWT_TOKEN')
        // 判断登录状态
    if (token) {
        if (to.path === '/login') {
            next({ path: '/' })
        } else {
            // 判断是否存入了roles 权限 说明路由已经挂载,, state被清除掉,
            let hasRoles = store.state.user.roles && store.state.user.roles.length > 0
            if (!hasRoles) {
                let userInfo = await store.dispatch('getUser')

                // 把当前登录用户对象所拥有的权限 和 本地的权限路由做对比 ,
                let routes = await store.dispatch('getAsyncRoutes', userInfo.roles)


                router.addRoutes(routes)
                next({...to, replace: true }) // 保证路由已挂载
            } else {
                next()
            }
        }
    } else {
        if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
            next()
        } else {
            next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
        }
    }
})

main.js

import './permission'

login.vue

doLogin() {
        this.$store.dispatch('login')
        this.$router.push('/')
    },