权限系统
概述
Naive Admin Max 提供路由级权限和按钮级权限两层权限控制方案。路由级权限通过路由守卫拦截未授权访问;按钮级权限通过 v-auth 指令或 auth() 函数控制页面内按钮的显隐。
路由级权限
路由级权限在路由守卫中实现,未登录用户访问受保护路由会被拦截并重定向至登录页。
typescript
// 路由守卫中的鉴权逻辑
router.beforeEach((to, from, next) => {
const token = localStorage.getItem(VITE_TOKEN_KEY)
if (!token && !whiteList.includes(to.path)) {
// 未登录且不在白名单中 → 重定向到登录页
next(`/login?redirect=${to.path}`)
} else {
next()
}
})按钮权限码
后端菜单接口的每个菜单项携带 actionList 字段,包含该页面下可用的操作权限码:
jsonc
{
"path": "/system/user",
"component": "templates/system/user/index",
"actionList": ["create", "update", "delete", "export"]
}登录后 userStore 将 actionList 存入 route.meta.actionList,供按钮级权限判断使用。
按钮级权限 — v-auth 指令
v-auth 是注册在全局的自定义指令(src/directives/auth.ts),用于根据权限码控制元素显隐。
字符串语法
判断是否拥有单个权限码:
vue
<template>
<!-- 拥有 'create' 权限码时显示 -->
<NButton v-auth="'create'">新增</NButton>
</template>数组语法
判断是否拥有数组中任意一个权限码:
vue
<template>
<!-- 拥有 'update' 或 'delete' 任一权限时显示 -->
<NButton v-auth="['update', 'delete']">操作</NButton>
</template>对象语法
更精细的控制,支持取反逻辑:
vue
<template>
<!-- 必须同时拥有 'create' 和 'update' 权限 -->
<NButton v-auth="{ code: ['create', 'update'], mode: 'every' }">
批量操作
</NButton>
</template>auth() 工具函数
当需要在非模板代码(如 render 函数、组合式函数)中判断权限时,使用 auth() 函数:
typescript
import { auth } from '@/directives/auth'
// 判断是否有 'delete' 权限
if (auth('delete')) {
// 显示删除按钮
}
// 在操作列配置中使用
const rowActions = useRowActions({
inline: [
{
label: '删除',
type: 'error',
auth: 'delete', // 内部调用 auth() 判断
onClick: (row) => handleDelete(row),
},
],
})权限判断来源
v-auth 和 auth() 都从当前路由的 meta.actionList 中读取权限码列表。如果 actionList 包含目标权限码,则视为有权限。
注意
按钮级权限仅控制 UI 显隐,不替代后端鉴权。后端接口仍需做权限校验,防止直接调用接口绕过前端限制。