vue 实现权限
Vue 实现权限管理的方法
路由权限控制
在Vue中可以通过路由守卫实现权限控制。在路由配置中添加meta字段标记权限,通过全局前置守卫检查用户权限。
// router.js
const router = new VueRouter({
routes: [
{
path: '/admin',
component: Admin,
meta: { requiresAuth: true, roles: ['admin'] }
}
]
})
router.beforeEach((to, from, next) => {
const currentUser = store.getters.currentUser
const requiresAuth = to.matched.some(record => record.meta.requiresAuth)
if (requiresAuth && !currentUser) {
next('/login')
} else if (to.meta.roles && !to.meta.roles.includes(currentUser.role)) {
next('/403')
} else {
next()
}
})
组件级权限控制
使用自定义指令v-permission控制组件显示,在全局注册指令。
// main.js
Vue.directive('permission', {
inserted: function(el, binding, vnode) {
const { value } = binding
const roles = store.getters.roles
if (value && value instanceof Array && value.length > 0) {
const hasPermission = roles.some(role => value.includes(role))
if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el)
}
} else {
throw new Error('需要指定权限数组')
}
}
})
// 组件中使用
<template>
<button v-permission="['admin']">管理员按钮</button>
</template>
按钮级权限控制
通过混入(mixin)或工具函数实现按钮权限判断。
// permission.js
export function checkPermission(permission) {
const permissions = store.getters.permissions
return permissions.includes(permission)
}
// 组件中使用
<template>
<button v-if="hasPermission('user:delete')">删除用户</button>
</template>
<script>
import { checkPermission } from '@/utils/permission'
export default {
methods: {
hasPermission(permission) {
return checkPermission(permission)
}
}
}
</script>
动态菜单生成
根据用户权限动态生成侧边栏菜单,过滤无权限的路由项。
// store.js
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)
})
}
}
function filterAsyncRoutes(routes, roles) {
return routes.filter(route => {
if (hasPermission(roles, route)) {
if (route.children) {
route.children = filterAsyncRoutes(route.children, roles)
}
return true
}
return false
})
}
API权限拦截
在请求拦截器中添加权限验证,对无权限的请求返回错误。
// axios拦截器
service.interceptors.request.use(
config => {
if (store.getters.token) {
config.headers['X-Token'] = getToken()
}
return config
},
error => {
return Promise.reject(error)
}
)
service.interceptors.response.use(
response => {
const res = response.data
if (res.code === 401) {
MessageBox.confirm('登录已过期', '重新登录', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
})
}
return res
},
error => {
return Promise.reject(error)
}
)
权限数据存储
使用Vuex管理权限状态,保持权限数据持久化。
// store/modules/permission.js
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)
})
}
}
权限系统设计要点
- 采用RBAC(基于角色的访问控制)模型
- 权限分为菜单权限、按钮权限、API权限
- 后端应提供权限验证接口
- 前端缓存权限数据减少请求
- 敏感操作需二次验证
- 定期审计权限分配情况
通过组合路由守卫、自定义指令、混入方法和状态管理,可以构建完整的Vue权限控制系统。实际项目中应根据业务复杂度选择合适的实现方案。







