Vue 权限管理终极实践:动态路由 + 按钮级权限控制
文章目录
- 一、权限管理整体思路
- 二、路由权限实现
- 三、按钮级权限指令实现
- 四、注意事项
- 五、完整流程图解
一、权限管理整体思路
在后台管理系统中,权限控制通常分为:
- 路由权限: 控制用户能否进入特定页面
- 按钮权限: 控制页面内操作按钮的显示/隐藏
- 菜单权限: 根据权限动态生成侧边栏菜单
采用以下技术方案:
- 动态路由: 通过接口获取权限列表,过滤出有权限得路由
- 自定义指令: 实现按钮级权限控制
- 递归组件: 生成动态菜单
二、路由权限实现
1.定义路由结构
// router/index.js
const constantRoutes = [{path: '/login',component: () => import('@/views/login'),hidden: true},{path: '/404',component: () => import('@/views/404'),hidden: true}
]const asyncRoutes = [{path: '/user',component: Layout,meta: { title: '用户管理', permission: ['admin'] },children: [{path: 'list',component: () => import('@/views/user/list'),meta: { title: '用户列表', permission: ['admin'] }}]},// ...其他路由
]
2.路由过滤逻辑
// utils/permission.js
export function filterRoutes(routes, permissions) {return routes.filter(route => {if (route.meta?.permission) {return route.meta.permission.some(p => permissions.includes(p))}return true}).map(route => {if (route.children) {route.children = filterRoutes(route.children, permissions)}return route})
}
3.动态注册路由
// store/modules/permission.js
actions: {generateRoutes({ commit }, permissions) {return new Promise(resolve => {let accessedRoutes = filterRoutes(asyncRoutes, permissions)// 添加404兜底accessedRoutes.push({ path: '*', redirect: '/404', hidden: true })commit('SET_ROUTES', accessedRoutes)resolve(accessedRoutes)})}
}// 登录后调用
const permissionList = ['admin'] // 从接口获取
const accessRoutes = await store.dispatch('permission/generateRoutes', permissionList)
router.addRoutes(accessRoutes)
三、按钮级权限指令实现
1.创建自定义指令
// directives/permission.js
export default {inserted(el, binding, vnode) {const { value } = bindingconst permissions = store.getters.permissionsif (value && value instanceof Array) {const hasPermission = permissions.some(p => value.includes(p))if (!hasPermission) {el.parentNode && el.parentNode.removeChild(el)}} else {throw new Error('权限值需为数组格式,例如 v-permission="[\'admin\']"')}}
}
2.全局注册指令
// main.js
import permission from './directives/permission'
Vue.directive('permission', permission)
3.使用示例
<template><el-button v-permission="['admin']">删除用户</el-button>
</template>
四、注意事项
1.路由匹配规则: 建议使用 name 作为权限标识,比 path 更稳定
2.404处理: 动态路由需最后添加404页面
3.页面刷新: 需在 Vuex 持久化存储权限数据
4.按钮隐藏方式: 推荐直接移除 DOM 而非隐藏,避免通过开发者工具修改
5.后端校验: 前端控制仅为体验优化,关键接口必须后端校验
五、完整流程图解
用户登录 → 获取权限列表 → 过滤路由 → 动态注册路由 → 生成菜单↓存储权限到Vuex → 按钮指令校验