vue2server7 7.0.46 → 7.0.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue2server7",
3
- "version": "7.0.46",
3
+ "version": "7.0.48",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "dev": "nodemon --watch src --ext ts --exec \"ts-node src/app.ts\"",
@@ -0,0 +1,206 @@
1
+ # Vue3 按钮权限控制(自定义指令 + Pinia 版)
2
+
3
+ ## 📌 目标
4
+
5
+ 实现一套企业级按钮权限控制方案:
6
+
7
+ - ✔ 从 Pinia 获取权限
8
+ - ✔ 支持单权限 / 多权限
9
+ - ✔ 支持 AND / OR 逻辑
10
+ - ✔ 支持动态更新权限
11
+ - ✔ 全局指令 v-permission
12
+ - ✔ 自动响应权限变化
13
+
14
+ ---
15
+
16
+ # 🧠 一、权限 Store(Pinia)
17
+
18
+ ```ts
19
+ // stores/auth.ts
20
+ import { defineStore } from 'pinia'
21
+
22
+ export const useAuthStore = defineStore('auth', {
23
+ state: () => ({
24
+ permissions: [] as string[],
25
+ }),
26
+
27
+ actions: {
28
+ setPermissions(perms: string[]) {
29
+ this.permissions = perms
30
+ },
31
+
32
+ clearPermissions() {
33
+ this.permissions = []
34
+ },
35
+ },
36
+ })
37
+ ```
38
+
39
+ ---
40
+
41
+ # 🧩 二、权限判断工具函数
42
+
43
+ ```ts
44
+ // utils/permission.ts
45
+
46
+ export type PermissionValue =
47
+ | string
48
+ | string[]
49
+ | { value: string[]; mode?: 'and' | 'or' }
50
+
51
+ export function hasPermission(
52
+ userPermissions: string[],
53
+ required?: PermissionValue
54
+ ): boolean {
55
+ if (!required) return true
56
+
57
+ if (typeof required === 'string') {
58
+ return userPermissions.includes(required)
59
+ }
60
+
61
+ if (Array.isArray(required)) {
62
+ return required.some(p => userPermissions.includes(p))
63
+ }
64
+
65
+ const { value, mode = 'or' } = required
66
+
67
+ if (mode === 'and') {
68
+ return value.every(p => userPermissions.includes(p))
69
+ }
70
+
71
+ return value.some(p => userPermissions.includes(p))
72
+ }
73
+ ```
74
+
75
+ ---
76
+
77
+ # ⚙️ 三、自定义指令 v-permission
78
+
79
+ ```ts
80
+ // directives/permission.ts
81
+ import type { Directive } from 'vue'
82
+ import { useAuthStore } from '@/stores/auth'
83
+ import { hasPermission } from '@/utils/permission'
84
+
85
+ export const permission: Directive = {
86
+ mounted(el, binding) {
87
+ const authStore = useAuthStore()
88
+
89
+ const check = () => {
90
+ const ok = hasPermission(authStore.permissions, binding.value)
91
+
92
+ if (!ok) {
93
+ el.remove()
94
+ }
95
+ }
96
+
97
+ check()
98
+ },
99
+
100
+ updated(el, binding) {
101
+ const authStore = useAuthStore()
102
+
103
+ const ok = hasPermission(authStore.permissions, binding.value)
104
+
105
+ if (!ok) {
106
+ el.remove()
107
+ }
108
+ },
109
+ }
110
+ ```
111
+
112
+ ---
113
+
114
+ # 🚀 四、全局注册指令
115
+
116
+ ```ts
117
+ // main.ts
118
+ import { createApp } from 'vue'
119
+ import App from './App.vue'
120
+ import { createPinia } from 'pinia'
121
+ import { permission } from '@/directives/permission'
122
+
123
+ const app = createApp(App)
124
+
125
+ app.use(createPinia())
126
+
127
+ app.directive('permission', permission)
128
+
129
+ app.mount('#app')
130
+ ```
131
+
132
+ ---
133
+
134
+ # 🧪 五、使用方式
135
+
136
+ ## ✔ 单权限
137
+
138
+ ```vue
139
+ <button v-permission="'user:add'">
140
+ 新增用户
141
+ </button>
142
+ ```
143
+
144
+ ---
145
+
146
+ ## ✔ 多权限(OR)
147
+
148
+ ```vue
149
+ <button v-permission="['user:add', 'user:edit']">
150
+ 新增 / 编辑
151
+ </button>
152
+ ```
153
+
154
+ ---
155
+
156
+ ## ✔ AND 权限
157
+
158
+ ```vue
159
+ <button
160
+ v-permission="{
161
+ value: ['user:add', 'user:delete'],
162
+ mode: 'and'
163
+ }"
164
+ >
165
+ 必须同时拥有权限
166
+ </button>
167
+ ```
168
+
169
+ ---
170
+
171
+ # ⚠️ 六、常见问题
172
+
173
+ ## ❌ Pinia 未初始化
174
+
175
+ ```ts
176
+ let authStore: any
177
+
178
+ function getStore() {
179
+ if (!authStore) {
180
+ authStore = useAuthStore()
181
+ }
182
+ return authStore
183
+ }
184
+ ```
185
+
186
+ ---
187
+
188
+ ## ❌ 权限不更新
189
+
190
+ ```ts
191
+ import { watch } from 'vue'
192
+
193
+ watch(
194
+ () => authStore.permissions,
195
+ () => {
196
+ // recheck
197
+ },
198
+ { deep: true }
199
+ )
200
+ ```
201
+
202
+ ---
203
+
204
+ # 🎯 总结
205
+
206
+ 适用于中后台系统的权限控制方案,支持扩展 RBAC / 路由权限 / 菜单权限。
@@ -218,3 +218,31 @@ el.style.pointerEvents = 'none'
218
218
  - 清晰
219
219
  - 可维护
220
220
  - 可扩展
221
+
222
+
223
+ type Button = {
224
+ appName: string
225
+ }
226
+
227
+ type Menu = {
228
+ children?: Menu[]
229
+ buttonChildren?: Button[]
230
+ }
231
+
232
+ export function getButtonPermissions(menuTree: Menu[]): string[] {
233
+ const set = new Set<string>()
234
+
235
+ const dfs = (nodes: Menu[]) => {
236
+ nodes.forEach(node => {
237
+ node.buttonChildren?.forEach(btn => {
238
+ if (btn.appName) set.add(btn.appName)
239
+ })
240
+
241
+ if (node.children) dfs(node.children)
242
+ })
243
+ }
244
+
245
+ dfs(menuTree)
246
+
247
+ return [...set]
248
+ }