40 lines
1.1 KiB
TypeScript
40 lines
1.1 KiB
TypeScript
import type { Directive, DirectiveBinding } from 'vue'
|
|
import { useUserStore } from '@/store'
|
|
|
|
type AuthValue = string | string[]
|
|
|
|
function normalize(binding: DirectiveBinding<AuthValue>): string[] {
|
|
const value = binding.value
|
|
if (Array.isArray(value)) return value
|
|
return value ? [value] : []
|
|
}
|
|
|
|
/** 校验不通过时直接移除 DOM 节点,而非仅禁用 */
|
|
function check(
|
|
el: HTMLElement,
|
|
binding: DirectiveBinding<AuthValue>,
|
|
checker: (code: string) => boolean,
|
|
) {
|
|
const codes = normalize(binding)
|
|
if (!codes.length) return
|
|
|
|
const passed = codes.some(checker)
|
|
if (!passed) {
|
|
el.remove()
|
|
}
|
|
}
|
|
|
|
/** 按钮级权限:v-hasPerm="'sys:user:add'" 或 v-hasPerm="['sys:user:add']" */
|
|
export const hasPerm: Directive<HTMLElement, AuthValue> = {
|
|
mounted(el, binding) {
|
|
check(el, binding, (code) => useUserStore().hasPermission(code))
|
|
},
|
|
}
|
|
|
|
/** 角色级权限:v-hasRole="'ADMIN'" */
|
|
export const hasRole: Directive<HTMLElement, AuthValue> = {
|
|
mounted(el, binding) {
|
|
check(el, binding, (code) => useUserStore().hasRole(code))
|
|
},
|
|
}
|