框架:vue-element-template
目标:自定义路由权限动态刷新侧边栏
1 从vue-element-admin 集成版的src/store/modules目录下把permission.js拷贝到vue-element-template的src/store/modules目录下
https://github.com/PanJiaChen/vue-element-admin/blob/master/src/store/modules/permission.js
import { asyncRoutes, constantRoutes } from '@/router'
/**
* Use meta.role to determine if the current user has permission
* @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
}
}
/**
* Filter asynchronous routing tables by recursion
* @param routes asyncRoutes
* @param roles
*/
export function filterAsyncRoutes(routes, roles) {
const res = []
routes.forEach(route => {
const tmp = { ...route }
if (hasPermission(roles, tmp)) {
if (tmp.children) {
tmp.children = filterAsyncRoutes(tmp.children, roles)
}
res.push(tmp)
}
})
return res
}
const state = {
routes: [],
addRoutes: []
}
const mutations = {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
}
}
const actions = {
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
let accessedRoutes
//超级管理员为admin角色,能访问所有路由
if (roles.includes('admin')) {
accessedRoutes = asyncRoutes || []
} else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
2 修改vue-element-template的src/store/modules目录下的user.js
import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import router, {resetRouter, sysRouters} from '@/router'
const getDefaultState = () => {
return {
token: getToken(),
name: '',
avatar: '',
roles:[] //添加角色变量
}
}
const state = getDefaultState()
const mutations = {
RESET_STATE: (state) => {
Object.assign(state, getDefaultState())
},
SET_TOKEN: (state, token) => {
state.token = token
},
SET_NAME: (state, name) => {
state.name = name
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
//添加VUEX保存角色信息
SET_ROLES: (state,roles) => {
state.roles = roles
}
}
//登陆认证
const actions = {
// user login
login({ commit }, userInfo) {
const { username, password } = userInfo
return new Promise((resolve, reject) => {
login({ username: username.trim(), password: password }).then(response => {
const { data } = response.data
commit('SET_TOKEN', data.token)
setToken(data.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
//获取用户信息
getInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo(state.token).then(response => {
const { data } = response.data
if (!data) {
return reject('Verification failed, please Login again.')
}
//存储用户信息
const { name, avatar,roles} = data
commit('SET_NAME', name)
commit('SET_AVATAR', avatar)
//存储角色信息
commit('SET_ROLES', roles)
resolve(data)
}).catch(error => {
reject(error)
})
})
},
// 退出登陆
logout({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
removeToken() // must remove token first
resetRouter()
commit('RESET_STATE')
//把角色信息设置为空列表
commit('SET_ROLES', [])
resolve()
}).catch(error => {
reject(error)
})
})
},
// remove token
resetToken({ commit }) {
return new Promise(resolve => {
removeToken() // must remove token first
commit('RESET_STATE')
//把角色信息设置为空列表
commit('SET_ROLES', [])
resolve()
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
3 修改vue-element-template的src/store目录下的getters.js
const getters = {
sidebar: state => state.app.sidebar,
device: state => state.app.device,
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
//角色
roles:state => state.user.roles,
//动态路由
permission_routes:state => state.permission.routes
}
export default getters
4 修改vue-element-template的src/store目录下的index.js
import Vue from 'vue' import Vuex from 'vuex' import getters from './getters' import app from './modules/app' import settings from './modules/settings' import user from './modules/user'
//导入 import permission from "@/store/modules/permission" Vue.use(Vuex) const store = new Vuex.Store({ modules: { app, settings, user,
//添加 permission }, getters }) export default store
5 修改vue-element-template的src/layout/components/Sidebar目录下的index.vue

6 修改vue-element-template的src/目录的permission.js
try {
// 注释掉原来的
// await store.dispatch('user/getInfo')
// next()
const { roles } = await store.dispatch('user/getInfo')
const accessRoutes = await store.dispatch('permission/generateRoutes',roles)
router.addRoutes(accessRoutes)
next({...to,replace:true})
} catch (error) {
// remove token and go to login page to re-login
await store.dispatch('user/resetToken')
Message.error(error || 'Has Error')
next(`/login?redirect=${to.path}`)
NProgress.done()
}
7 修改vue-element-template的src/router目录的index.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
//公共路由
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/',
component: Layout,
// redirect: '/dashboard',
children: [{
path: 'dashboard',
name: 'LazyOps',
component: () => import('@/views/dashboard/index'),
meta: { title: 'LazyOps', icon: 'el-icon-s-home'}
}]
},
// 404 page must be placed at the end !!!
]
//动态路由
export const asyncRoutes = [
{
path: '/system',
component: Layout,
redirect: '/system/user',
alwaysShow:true,
name: '系统管理',
meta: { title: '系统管理', icon: 'el-icon-s-tools',roles:['admin','test']},
children: [
{
path: 'user',
name: '用户列表',
component: () => import('@/views/rbac/users'),
meta: { title: '用户列表', icon: 'table',roles:['admin','test']}
},
{
path: 'role',
name: '角色列表',
component: () => import('@/views/rbac/roles'),
meta: { title: '角色列表', icon: 'table',roles:['admin']}
}
]
},
{ path: '*', redirect: '/404', hidden: true },
]
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
const router = createRouter()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router