框架: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