91 lines
2.0 KiB
Markdown
91 lines
2.0 KiB
Markdown
# 9.7 权限控制
|
|
|
|
:::tip 概述
|
|
前端权限控制通过 `v-perm` / `v-perms` 指令实现按钮级权限控制。
|
|
:::
|
|
|
|
## 权限指令
|
|
|
|
### v-perm(单权限)
|
|
|
|
```vue
|
|
<template>
|
|
<!-- 只有拥有 sys:user:add 权限的用户才能看到此按钮 -->
|
|
<el-button v-perm="'sys:user:add'" type="primary">新增</el-button>
|
|
</template>
|
|
```
|
|
|
|
### v-perms(多权限,满足任一即可)
|
|
|
|
```vue
|
|
<template>
|
|
<!-- 拥有 sys:user:add 或 sys:user:update 任一权限即可 -->
|
|
<el-button v-perms="['sys:user:add', 'sys:user:update']">操作</el-button>
|
|
</template>
|
|
```
|
|
|
|
## 指令实现
|
|
|
|
```typescript
|
|
// src/directives/permission.ts
|
|
|
|
import { usePermission } from '@/hooks/web/usePermission';
|
|
|
|
export const perm: ObjectDirective = {
|
|
mounted(el: HTMLButtonElement, binding) {
|
|
const { hasSomePermission } = usePermission();
|
|
if (!hasSomePermission(binding.value)) {
|
|
el.parentNode.removeChild(el); // 无权限则移除元素
|
|
}
|
|
},
|
|
};
|
|
```
|
|
|
|
## usePermission Hook
|
|
|
|
:::tip 超级管理员
|
|
用户权限列表包含 `*:*:*` 时,表示超级管理员,拥有所有权限。
|
|
:::
|
|
|
|
```typescript
|
|
// src/hooks/web/usePermission.ts
|
|
|
|
export function usePermission() {
|
|
const userStore = useUserStore();
|
|
|
|
/**
|
|
* 检查是否拥有指定权限
|
|
* 超级管理员(permissions 包含 '*:*:*')拥有所有权限
|
|
*/
|
|
function hasSomePermission(permission: string | string[]): boolean {
|
|
const perms = userStore.permissions;
|
|
if (perms.includes('*:*:*')) return true;
|
|
|
|
if (typeof permission === 'string') {
|
|
return perms.includes(permission);
|
|
}
|
|
return permission.some((p) => perms.includes(p));
|
|
}
|
|
|
|
return { hasSomePermission, hasEveryPermission };
|
|
}
|
|
```
|
|
|
|
## 权限数据来源
|
|
|
|
用户登录后,`/index/getUser` 接口返回权限列表:
|
|
|
|
```json
|
|
{
|
|
"permissions": [
|
|
"sys:user:page",
|
|
"sys:user:add",
|
|
"sys:user:update",
|
|
"sys:user:delete",
|
|
"sys:role:page",
|
|
"..."
|
|
]
|
|
}
|
|
```
|
|
|
|
超级管理员返回 `["*:*:*"]`,拥有所有权限。 |