element-admin路由权限配置详解(二)
一、项目权限分析
一个项目我们如何做好权限管理,取决于项目实际应用场景,比如说我们要做一个内容管理后台,可能只是简单的几个角色,我们就没有必要做的很复杂,只是需要一个权限模块,分为超级管理员,中级管理员,普通管理员,然后在新建用户的时候绑定到用户表上就行了,这样就可以满足日常需求了,这样的权限完全有我们上次讲到就完全够用了。
上一章我们讲解了基本的路由权限配置,从router.js到vuex,再到permission.js,整个流程做了一个梳理,如何配置,如何应用。在上一章中,我们大致将权限分为几个部分,比如:超级管理员,中级管理员,普通管理员等等,根据登录用户不同身份加载我们事先约定好的路由,当然在大型项目中可能会有很多的局限性,不够灵活,今天我们要讲的就是如何在单个路由做前端控制,通过用户信息返回roles列表,加载路由。
二、路由改造
如下所示,在需要加权限的路由上加上authority字段,默认路由不加authority所有权限下都可见。
// src/router/index.js
const routes = [
{
path: '/article',
mete: { title: '内容管理'},
redirect: '/article/list',
children: [
{
path: 'list',
meta: { title: '文章列表'},
authority: ['user'],
component: () => import('@/views/article/list'),
},
{
path: 'image',
meta: { title: '图片管理'},
authority: ['admin'],
component: () => import('@/views/article/image'),
}
]
},{
path: 'user',
meta: { title: '用户管理'},
authority: ['user', 'admin'],
component: () => import('@/views/user/index'),
}
]
三、路由权限方法使用
权限相关方法主要使用在store中的permission.js文件中,对导入的路由列表进行过滤,具体逻辑可以参考element-admin路由权限配置详解(一)
// utils/permission.js
/**
* 跟进用户权限过滤路由列表
* @param {Array} routes 路由列表
* @returns
*/
export function getAuthRoutes(routes) {
if (routes && routes.length) {
return routes.filter((v) => {
if (v.children) {
v.children = getAuthRoutes(v.children)
if (v.children.length === 1) {
onlyOnechildrenRoute(v)
}
if (v.children == null || v.children.length == 0) return false
} else if (!verifyAuthority(v)) {
return false
}
return true
})
}
return routes
}
/**
* 根据权限过滤后子路由children只有一个时,
* 判断父路由redirect地址是否在children存在
* 不存在children的第一个path为父的redreact path
*/
function onlyOnechildrenRoute(route) {
route.redirect = route.children[0].path
}
/**
* 验证路由上的权限是否存在
* 根据用户返回权限列表判断当前路由是否通过
* @param {Object} route 路由对象
* @returns
*/
function verifyAuthority(route) {
if (!route.authority) return true
// getAuthority 返回的是登录用户信息返回的roles,可以保存在store中或者localStorage中
const roles = getAuthority()
return route.authority.some((citem) => roles.includes(citem))
}
四、permission.js 修改
import router from './router'
import store from './store'
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'] // no redirect whitelist
// eslint-disable-next-line
router.beforeEach(async (to, from, next) => {
NProgress.start()
document.title = getPageTitle(to.meta.title)
const hasToken = getToken()
if (hasToken) {
if (to.path === '/login') {
next({ path: '/' })
NProgress.done()
} else {
const hasGetUserInfo = store.getters.name
if (!hasGetUserInfo) {
try {
// get user info
await store.dispatch('user/getInfo')
} catch (error) {
// remove token and go to login page to re-login
await store.dispatch('user/resetToken')
next()
NProgress.done()
}
}
// 获取路由
if (!store.getters.routes.length) {
const routes = await store.dispatch('permission/GenerateRoutes')
router.addRoutes(routes)
next({ path: to.path, query: to.query, replace: true })
NProgress.done()
} else {
next()
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(() => {
NProgress.done()
})
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现