vue-element-admin 是一个后台前端解决方案,不太适合当基础模板来进行二次开发,因此 vue-admin-template基础纯净版,涉及的权限问题,基本实现思路
1.创建vue实例将vue-router挂载,此时vue-router挂载一些登录或者不用权限的公用的页面
2.用户登录后,获取role,,将role和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表
3.调用router.addRoutes添加用户可访问的路由
4.使用vuex管理路由表,根据vuex中可访问的路由渲染侧边栏组件
router.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
/**
*不需要权限可以直接访问的界面
*例如登录页面,404等
*/
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: 'dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: '首页', icon: 'dashboard' }
}]
},
{ path: '*', redirect: '/404', hidden: true }
]
/**
*异步挂载的路由
*动态需要根据权限加载的路由表
/
export const asyncRoutes = [
{
path: '/example',
component: Layout,
// redirect: '/example/table',
name: 'example',
meta: { title: '测试', icon: 'example',roles:['admin'] },
children: [
{
path: 'table',
name: 'Table',
component: () => import('@/views/table/index'),
meta: { title: 'Table', icon: 'table' }
},
{
path: 'tree',
name: 'Tree',
component: () => import('@/views/tree/index'),
meta: { title: 'Tree', icon: 'tree' }
}
]
},
{ path: '*', redirect: '/404', hidden: true }
];
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
const router = createRouter()
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router
比较关键的部分 src/promission.js
基本是是从vue-element-admin 复制过来
import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'
NProgress.configure({ showSpinner: false }) // NProgress Configuration
const whiteList = ['/login', '/auth-redirect'] //白名单
router.beforeEach(async(to, from, next) => {
// start progress bar
NProgress.start()
// set page title
document.title = getPageTitle(to.meta.title)
// determine whether the user has logged in
const hasToken = getToken()
if (hasToken) { //判断是否有token
if (to.path === '/login') {
// if is logged in, redirect to the home page
next({ path: '/' })
NProgress.done()
} else {
// 确定用户是否通过getInfo获得了他的权限角色
const hasRoles = store.getters.roles && store.getters.roles.length > 0
if (hasRoles) {
next()
} else {
try {
// 获取用户信息
const { roles } = await store.dispatch('user/getInfo')
// 根据角色生成可访问路由映射
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
//动态添加可访问路由
router.addRoutes(accessRoutes)
console.log(accessRoutes)
// hack method to ensure that addRoutes is complete
// set the replace: true, so the navigation will not leave a history record
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()
}
}
}
} else {
/* has no token*/
if (whiteList.indexOf(to.path) !== -1) {
// in the free login whitelist, go directly
next()
} else {
// other pages that do not have permission to access are redirected to the login page.
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
})
router.afterEach(() => {
// finish progress bar
NProgress.done()
})
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
if (roles.includes('admin')) {
accessedRoutes = asyncRoutes || []
} else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
最后一步,侧边栏遍历 v-for 算出来permission_routers,就不贴代码了