vue权限实现原理
Vue权限实现原理
Vue权限控制的核心在于动态路由和组件级权限校验,通常结合后端返回的权限数据实现。以下是常见的实现方式:
路由级权限控制
路由级权限通过动态生成可访问路由表实现。用户登录后获取权限列表,过滤出有权限的路由并动态添加到Router实例中。
// 示例:动态路由过滤
const asyncRoutes = [
{ path: '/admin', component: Admin, meta: { roles: ['admin'] }},
{ path: '/user', component: User, meta: { roles: ['user', 'admin'] }}
]
function filterRoutes(routes, roles) {
return routes.filter(route => {
if (route.meta?.roles) {
return roles.some(role => route.meta.roles.includes(role))
}
return true
})
}
组件级权限控制
组件内使用自定义指令或函数式组件实现细粒度控制。常见的v-permission指令实现方式:
// 注册全局指令
Vue.directive('permission', {
inserted(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)
}
}
}
})
// 使用方式
<button v-permission="['admin']">删除</button>
按钮级权限控制
通过全局混入或工具函数实现按钮显隐控制。典型实现方案:
// 全局混入方案
Vue.mixin({
methods: {
checkPermission(permission) {
return this.$store.getters.permissions.includes(permission)
}
}
})
// 使用方式
<button v-if="checkPermission('user:delete')">删除用户</button>
权限数据存储
权限数据通常存储在Vuex或Pinia中,与用户信息一起在登录时获取:
// Vuex示例
const store = new Vuex.Store({
state: {
roles: [],
permissions: []
},
actions: {
async getUserInfo({ commit }) {
const { roles, permissions } = await api.getUserInfo()
commit('SET_ROLES', roles)
commit('SET_PERMISSIONS', permissions)
}
}
})
权限验证流程
完整的权限验证流程包含以下环节:
- 用户登录获取token
- 请求用户权限数据
- 过滤异步路由表
- 动态添加路由
- 渲染有权限的菜单和按钮
// 登录后处理流程示例
async login() {
const token = await api.login(this.form)
const { roles } = await api.getUserInfo()
const accessedRoutes = filterRoutes(asyncRoutes, roles)
router.addRoutes(accessedRoutes)
// 存储权限数据
store.commit('SET_ROLES', roles)
}
权限持久化方案
为保证刷新后权限不丢失,通常采用以下策略:
- 将权限数据存入sessionStorage/localStorage
- 每次刷新时重新验证token并获取权限
- 路由跳转前进行权限校验(路由守卫)
router.beforeEach(async (to, from, next) => {
if (hasToken()) {
if (!hasRoles()) {
try {
const roles = await store.dispatch('getUserInfo')
const routes = await store.dispatch('generateRoutes', roles)
router.addRoutes(routes)
next({ ...to, replace: true })
} catch (error) {
next('/login')
}
} else {
next()
}
} else {
next('/login')
}
})
服务端权限校验
前端权限控制需配合后端接口校验。常见模式包括:
- JWT中嵌入权限声明
- 每个API请求携带权限标识
- 后端对敏感接口进行二次验证
// 请求拦截器示例
axios.interceptors.request.use(config => {
if (store.getters.token) {
config.headers['X-Access-Token'] = getToken()
}
return config
})
以上方案可根据实际项目需求组合使用,建议路由级控制用于整体页面访问权限,指令方式用于组件内细粒度控制。权限数据建议采用树形结构存储,便于实现多级权限管理。







