权限相关
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('/')
},