com-angel-authorization

Framework-agnostic user permission toolkit for React and Vue
7,496
Install
npm install com-angel-authorization
Latest Version:2.1.0
Vue:3
License:MIT
Last Updated:Sep 21, 2026
Links: npm
Maintainer: yilia888

com-angel-authorization

框架无关的用户权限配置 npm 包,可在 React 与 Vue 3 项目中使用。

特性

  • 核心层与 UI 框架解耦,也可直接在非前端环境使用
  • 支持权限码(permission)与角色(role)
  • any / all 匹配模式
  • 超级管理员旁路(isSuperAdmin)
  • React:Provider + Hooks + <Can>
  • Vue 3:Plugin + Composables + v-permission + <Can>

本地预览

npm install
npm run demo

浏览器会打开 http://localhost:5173,可体验权限点管理的增删改查(Mock 数据,无需后端)。


安装

npm install com-angel-authorization
# 或
pnpm add com-angel-authorization

按需安装 peer 依赖:

# React 项目
npm install react

# Vue 项目
npm install vue

包入口

入口 用途
com-angel-authorization 框架无关核心
com-angel-authorization/react React 适配
com-angel-authorization/vue Vue 3 适配

核心 API(框架无关)

import { createPermissionStore } from 'com-angel-authorization';

const store = createPermissionStore({
  permissions: ['user:view', 'user:edit'],
  roles: ['editor'],
  isSuperAdmin: false,
});

store.hasPermission('user:edit'); // true
store.hasPermission(['user:edit', 'user:delete'], { mode: 'all' }); // false
store.hasRole('editor'); // true
store.can('user:view'); // true(hasPermission 别名)

// 登录后写入
store.hydrate({
  permissions: ['user:view', 'user:edit', 'user:delete'],
  roles: ['admin'],
});

// 登出清空
store.clear();

React 用法

import {
  PermissionProvider,
  usePermission,
  useHasPermission,
  Can,
} from 'com-angel-authorization/react';

function App() {
  return (
    <PermissionProvider
      initialState={{
        permissions: ['user:view', 'user:edit'],
        roles: ['editor'],
      }}
    >
      <Dashboard />
    </PermissionProvider>
  );
}

function Dashboard() {
  const { can, hydrate, clear } = usePermission();
  const canEdit = useHasPermission('user:edit');

  // 登录成功后
  // hydrate({ permissions: data.perms, roles: data.roles });

  // 登出
  // clear();

  return (
    <div>
      {canEdit && <button>编辑</button>}

      <Can permission="user:delete" fallback={<span>无删除权限</span>}>
        <button>删除</button>
      </Can>

      <Can permission={['user:edit', 'user:delete']} mode="all">
        <AdminTools />
      </Can>

      <Can role="admin" permission="user:edit" combine="or">
        <button>管理入口</button>
      </Can>

      {can('user:view') && <UserList />}
    </div>
  );
}

也可传入外部 store,便于跨树或与路由守卫共享:

import { createPermissionStore } from 'com-angel-authorization';
import { PermissionProvider } from 'com-angel-authorization/react';

export const permissionStore = createPermissionStore();

<PermissionProvider store={permissionStore}>
  <App />
</PermissionProvider>

Vue 3 用法

安装插件

import { createApp } from 'vue';
import { createPermissionPlugin, Can } from 'com-angel-authorization/vue';
import App from './App.vue';

const permission = createPermissionPlugin({
  initialState: {
    permissions: ['user:view', 'user:edit'],
    roles: ['editor'],
  },
});

const app = createApp(App);
app.use(permission);
app.component('Can', Can); // 可选:全局注册
app.mount('#app');

// 需要时在模块外访问
// permission.store.hydrate({ ... })

Composition API

<script setup lang="ts">
import { usePermission, useHasPermission, Can } from 'com-angel-authorization/vue';

const { can, hydrate, clear } = usePermission();
const canEdit = useHasPermission('user:edit');

async function onLogin() {
  const data = await fetchUserAuth();
  hydrate({
    permissions: data.permissions,
    roles: data.roles,
    isSuperAdmin: data.isSuperAdmin,
  });
}
</script>

<template>
  <button v-if="canEdit">编辑</button>

  <Can permission="user:delete">
    <button>删除</button>
    <template #fallback>无删除权限</template>
  </Can>

  <!-- 指令:无权限时隐藏元素 -->
  <button v-permission="'user:edit'">编辑</button>
  <button v-permission:all="['user:edit', 'user:delete']">危险操作</button>
  <button v-permission:role="'admin'">管理员</button>
  <button
    v-permission="{
      permission: 'user:edit',
      role: 'admin',
      combine: 'or',
    }"
  >
    管理入口
  </button>
</template>

选项式 / 模板全局方法

插件安装后可用:

<template>
  <button v-if="$can('user:edit')">编辑</button>
  <button v-if="$hasRole('admin')">管理</button>
</template>

API 速查

PermissionStore

方法 说明
hydrate(state) 一次性写入权限 / 角色 / 超管
setPermissions(list) 设置权限码
setRoles(list) 设置角色
setSuperAdmin(bool) 设置超管
clear() 清空
hasPermission(codes, { mode }) 校验权限,mode: any | all
hasRole(codes, { mode }) 校验角色
can(codes, options) hasPermission 别名
subscribe(listener) 订阅变更,返回取消函数
getState() 获取当前快照

<Can> 组件(React / Vue)

Prop 说明
permission 权限码或数组
role 角色码或数组
mode any(默认)/ all
combine 同时传 permission 与 role 时:and(默认)/ or
fallback React:无权限占位;Vue:使用 #fallback 插槽

权限点管理(CRUD)

对接后端 /authorization-resources,提供列表 / 新增 / 编辑 / 删除。

操作 方法 地址
列表 GET /authorization-resources?type=api&page-token=&page-size=&page-direction=
新增 POST /authorization-resources
修改 PATCH /authorization-resources/{resource-id}
删除 DELETE /authorization-resources/{resource-id}

新增时 resourceId 由 getAppClientId() 生成,type 固定为 api。

React

import {
  ResourceManager,
  createAuthorizationResourceApi,
  createDefaultResourceRequest,
} from 'com-angel-authorization/react';

const api = createAuthorizationResourceApi(
  createDefaultResourceRequest({ baseUrl: '/api' }),
);

export function Page() {
  return <ResourceManager api={api} />;
}

也可注入宿主已有请求(如 Angel_HGAMS 的 apiGetJson):

import { createAuthorizationResourceApi } from 'com-angel-authorization';
import { apiDeleteJson, apiGetJson, apiPatchJson, apiPostJson } from './request';

const api = createAuthorizationResourceApi(async ({ method, url, body, signal }) => {
  if (method === 'GET') return apiGetJson(url, { signal });
  if (method === 'POST') return apiPostJson(url, body, { signal });
  if (method === 'PATCH') return apiPatchJson(url, body, { signal });
  return apiDeleteJson(url, { signal });
});

Vue 3

import { createApp } from 'vue';
import {
  ResourceManager,
  createAuthorizationResourceApi,
  createDefaultResourceRequest,
} from 'com-angel-authorization/vue';

const api = createAuthorizationResourceApi(
  createDefaultResourceRequest({ baseUrl: '/api' }),
);

createApp(ResourceManager, { api }).mount('#app');

表单字段

字段 说明
name 权限名称(文本)
identification 接口标识(文本)
status 1 启用 / 0 禁用
private 是否私有资源
description 描述

列表表头:权限名称、接口标识、描述、状态、操作。


菜单管理(CRUD)

对接同一后端 /authorization-resources,按 type 区分菜单与权限点。

操作 方法 地址
列表 GET /authorization-resources?type=page,menu,button&depth=1&page-token=&page-size=&page-direction=
展开下级 GET /authorization-resources/{resource-id}/sub-resources
新增 POST /authorization-resources
修改 PATCH /authorization-resources/{resource-id}
删除 DELETE /authorization-resources/{resource-id}
权限点下拉 GET /authorization-resources?type=api&keyword=(输入关键字后带 keyword 搜索)
字段列表 GET /authorization-resources/{resource-id}/fields
新增字段 POST /authorization-resources/{resource-id}/fields
修改字段 PATCH /authorization-resources/{resource-id}/fields/{field-key}
删除字段 DELETE /authorization-resources/{resource-id}/fields/{field-key}

新增时 resourceId 由 getAppClientId() 生成;上级选择「无」时 parentId 传 null。

React

import {
  MenuManager,
  createMenuResourceApi,
  createDefaultResourceRequest,
} from 'com-angel-authorization/react';

const api = createMenuResourceApi(
  createDefaultResourceRequest({ baseUrl: '/api' }),
);

export function Page() {
  return <MenuManager api={api} />;
}

表单字段

字段 说明
parentId 上级菜单(表单内只读展示;行内「新增」默认当前项,顶部「新增」为无)
depth 菜单层级(页面不展示;无上级为 1,否则上级 depth + 1,提交时自动带上)
type page 目录 / menu 菜单 / button 按钮
name 菜单名称
sort 显示排序(数值越小越靠前)
identification 请求地址
permissionPointIds 权限标识(多选,来自 type=api 列表)
status 1 显示 / 0 隐藏

列表默认 depth=1。返回项 leaf=1 表示无下级;否则可点击展开,请求 /authorization-resources/{resource-id}/sub-resources。

列表表头:菜单名称、请求地址、类型、可见、权限标识、操作(新增 / 编辑 / 数据列 / 删除)。

权限标识列优先取返回的 permissionPoints[].name,用 、 拼接展示。

点击「数据列」打开「页面数据列配置」弹窗(仅 type=menu 的菜单项显示该按钮),维护本页面可授权字段(fieldKey / name / description / viewTypes:LIST | DETAIL | EXPORT)。字段标识创建后不可修改;删除字段会同步清理角色侧该字段可见性配置。


角色管理(CRUD)

对接后端 /system/roles。

操作 方法 地址
列表 GET /system/roles?keyword=&page-token=&page-size=&page-direction=
新增 POST /system/roles
修改 PATCH /system/roles/{role-id}
删除 DELETE /system/roles/{role-id}
授权树 GET /system/roles/{role-id}/permissions
保存授权 POST /system/roles/{role-id}/permissions
数据范围 GET /system/roles/{role-id}/default-data-scope
保存数据范围 PUT /system/roles/{role-id}/default-data-scope
页面授权树 GET /system/roles/{role-id}/page-data-authorizations
页面授权配置 GET /system/roles/{role-id}/page-data-authorizations/{resource-id}
保存页面授权 PUT /system/roles/{role-id}/page-data-authorizations/{resource-id}
删除页面例外 DELETE /system/roles/{role-id}/page-data-authorizations/{resource-id}

授权树返回 resourceIds(已勾选资源 ID)与 resourceTree(含 name / children 的树)。保存时提交 { resourceIds }。

React

import {
  RoleManager,
  createSystemRoleApi,
  createDefaultResourceRequest,
} from 'com-angel-authorization/react';

const api = createSystemRoleApi(
  createDefaultResourceRequest({ baseUrl: '/api' }),
);

export function Page() {
  return <RoleManager api={api} />;
}

表单字段

字段 说明
name 角色名称
description 角色描述

列表支持 keyword 搜索与 page-token 分页。表头:角色名称、描述、操作(编辑 / 菜单授权 / 数据授权 / 页面授权 / 删除)。

点击「菜单授权」打开树形勾选弹窗(父子联动:勾选父节点级联子节点;子节点全选/取消会回写父节点;部分勾选为半选态)。保存调用 POST /system/roles/{role-id}/permissions。

点击「数据授权」打开数据范围弹窗:scopeType 为 ALL / USER_GROUP / CUSTOM / SELF;选「自定义部门数据」时需至少勾选一个部门(部门列表来自 GET /system/groups)。保存调用 PUT /system/roles/{role-id}/default-data-scope,body 为 { scopeType, departmentIds }(非 CUSTOM 时 departmentIds 为空数组)。

点击「页面授权」打开页面数据授权弹窗:左侧为已授权业务页面树(GET .../page-data-authorizations);选中页面后加载例外配置(GET .../page-data-authorizations/{resource-id},scopeType=null 表示继承默认)与登记字段(GET /authorization-resources/{resource-id}/fields)。本页数据范围可选继承默认 / 本部门 / 全部数据 / 自定义部门;点击「继承默认」立即 DELETE 页面例外。保存调用 PUT .../page-data-authorizations/{resource-id},提交完整 fieldPermissions。


用户管理(CRUD)

对接后端 /system/users。

操作 方法 地址
列表 GET /system/users?keyword=&enabled=&page-token=&page-size=&page-direction=
新增 POST /system/users
修改 PATCH /system/users/{user-id}
删除 DELETE /system/users/{user-id}
重置密码 POST /system/users/{user-id}/reset-password(body: { password })
部门下拉 GET /system/groups?keyword=
角色下拉 GET /system/roles?keyword=&page-size=500&page-token=&page-direction=current

React

import {
  UserManager,
  createSystemUserApi,
  createDefaultResourceRequest,
} from 'com-angel-authorization/react';

const api = createSystemUserApi(
  createDefaultResourceRequest({ baseUrl: '/api' }),
);

export function Page() {
  return <UserManager api={api} />;
}

表单字段

字段 说明
username 账号,必填,按普通字符串处理
name 用户名
password 初始密码(仅新增时填写;编辑请用「重置密码」)
groupIds 归属部门,必填;进入模块时请求 /system/groups,列表按 name 展示,表单下拉多选
roleIds 用户角色,多选(/system/roles)
enabled 是否启用(boolean,Switch,靠左)

列表支持 keyword、enabled 过滤与 page-token 分页。


系统管理(含子菜单)

将「菜单管理」「权限点管理」「角色管理」「用户管理」作为「系统管理」的子菜单展示:

import {
  SystemAdmin,
  createMenuResourceApi,
  createAuthorizationResourceApi,
  createSystemRoleApi,
  createSystemUserApi,
  createDefaultResourceRequest,
  SYSTEM_ADMIN_MENU,
} from 'com-angel-authorization/react';

const request = createDefaultResourceRequest({ baseUrl: '/api' });
const menuApi = createMenuResourceApi(request);
const resourceApi = createAuthorizationResourceApi(request);
const roleApi = createSystemRoleApi(request);
const userApi = createSystemUserApi(request);

// 侧栏:系统管理 → 菜单 / 权限点 / 角色 / 用户管理
<SystemAdmin
  menuApi={menuApi}
  resourceApi={resourceApi}
  roleApi={roleApi}
  userApi={userApi}
/>

// 也可把菜单结构接到自有路由
console.log(SYSTEM_ADMIN_MENU);
// { key: 'system', label: '系统管理', children: [
//   { key: 'menu', label: '菜单管理' },
//   { key: 'resource', label: '权限点管理' },
//   { key: 'role', label: '角色管理' },
//   { key: 'user', label: '用户管理' },
// ]}

典型接入流程

  1. 应用启动时创建 store / 安装 Provider 或 Plugin
  2. 登录成功后调用 hydrate 写入后端返回的权限与角色
  3. 页面用 <Can> / v-permission / can() 控制按钮与菜单
  4. 路由守卫中直接读同一个 store 做页面级鉴权
  5. 登出时调用 clear()
// 路由守卫示例(与框架无关)
if (!permissionStore.hasPermission('order:view')) {
  return next('/403');
}

构建

npm install
npm run build
./scripts/publish.sh minor 
npm install com-angel-authorization@latest

产物在 dist/,支持 ESM / CJS 与类型声明。

License

MIT

Related Packages

permix

Permix is a lightweight, framework-agnostic, type-safe permissions management li...

385,566 640
@composy/permission-vue

LDesign 权限系统 Vue 3 适配层 / Vue 3 adapter for @composy/permission-core

0
vue-nuxt-permission

A unified permission system for Vue 3 and Nuxt 3 / Nuxt 4 with directives, guard...

2,570 0
@better-iam/vue

Vue 3 bindings for Better IAM: a plugin, composables for the session and authori...

782 6
@casl/vue

Vue plugin for CASL which makes it easy to add permissions in any Vue applicatio...

3,634,633 7,105

Version History

Version Released Vue License
2.1.0 >=3.0.0 MIT
2.0.15 >=3.0.0 MIT
2.0.13 >=3.0.0 MIT
2.0.12 >=3.0.0 MIT
2.0.11 >=3.0.0 MIT