Skip to content

菜单与按钮权限

Forge 前端通过动态路由和权限指令实现菜单级和按钮级权限控制。你需要理解权限的运作方式来正确控制页面元素的显示。

权限层级

层级控制方式说明
菜单权限动态路由用户能看到哪些菜单
接口权限@SaCheckPermission后端控制接口能否访问
按钮权限v-permission 指令页面内按钮显示/隐藏

菜单权限

菜单从后端接口加载,根据当前用户角色动态生成路由:

typescript
// permission store 中生成路由
async function generateRoutes() {
  const res = await getMenus()
  const routes = filterAsyncRoutes(res.data)
  routes.forEach(route => router.addRoute(route))
  return routes
}

未授权的菜单不会出现在侧边栏中,直接访问 URL 也会被路由守卫拦截。

按钮权限

v-permission 指令

vue
<template>
  <!-- 有权限才显示 -->
  <NButton v-permission="'biz:order:add'" @click="handleAdd">新增</NButton>

  <!-- 无权限时隐藏 -->
  <NButton v-permission="'biz:order:remove'" @click="handleDelete">删除</NButton>
</template>

usePermission 组合式函数

javascript
import { usePermission } from '@/composables/usePermission'

const { hasPermission } = usePermission()

// 条件判断
const canEdit = computed(() => hasPermission('biz:order:edit'))
const canDelete = computed(() => hasPermission('biz:order:remove'))
vue
<template>
  <a v-if="canEdit" class="text-primary" @click="handleEdit">编辑</a>
  <a v-if="canDelete" class="text-error" @click="handleDelete">删除</a>
</template>

多权限判断

javascript
// 满足任意一个权限
const canManage = computed(() =>
  hasPermission('biz:order:add') || hasPermission('biz:order:edit')
)

// 满足全部权限
const canAudit = computed(() =>
  hasPermission('biz:order:add') && hasPermission('biz:order:audit')
)

权限标识命名

权限标识与后端 @SaCheckPermission 注解值保持一致:

格式示例
模块:业务:操作biz:order:add
模块:业务:操作system:user:remove
操作标识
查询list / query
新增add
修改edit
删除remove
导出export
导入import

菜单过滤

typescript
function filterAsyncRoutes(routes: RouteRecordRaw[], roles: string[]) {
  const result: RouteRecordRaw[] = []
  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      result.push(tmp)
    }
  })
  return result
}

AiCrudPage 权限控制

javascript
const apiConfig = {
  page: 'GET@/biz/order/page',       // 需 biz:order:list
  get: 'GET@/biz/order/:id',         // 需 biz:order:query
  add: 'POST@/biz/order',            // 需 biz:order:add
  edit: 'PUT@/biz/order',            // 需 biz:order:edit
  delete: 'DELETE@/biz/order/:id'    // 需 biz:order:remove
}

const schema = computed(() => [
  // 操作列按钮根据权限自动显示/隐藏
  { field: 'actions', label: '操作', component: 'AiTableActions' }
])

注意事项

  • 前端权限控制只是隐藏 UI,真正的安全防线在后端 @SaCheckPermission
  • 权限标识必须前后端一致
  • 按钮权限优先用 v-permission 指令,比 v-if 更简洁
  • 菜单路由从后端加载,不在前端代码中硬编码

Forge Admin — 基于 Vue3 + Spring Boot 的企业级后台管理框架