1、hook函数
1.1、hasPermission 函数 api
| 参数字段 | 类型 | 说明 |
|---|
| value | string | string[] | 权限字符串,支持数组 |
| and | boolean | 权限字符串多个情况下,and 为 true 即都需要满足,默认为 false |
1.2、hook 示例
import { computed } from 'vue'
import { usePermission } from '@/hooks/web/usePermission'
const { hasPermission } = usePermission()
const available1 = computed(() => hasPermission('p:bb'))
const available2 = computed(() => hasPermission(['p:aa', 'p:bb']))
const available3 = computed(() => hasPermission(['p:aa', 'p:bb'], true))
1.2、hook函数代码
import { intersection } from 'lodash-es'
import { isArray } from '@/utils/is'
import { useUserStoreWithOut } from '@/store/modules/user'
export const AllPermissions = ['*.*.*']
export function usePermission() {
const userStore = useUserStoreWithOut()
const hasPermission = (value: string | string[], and = false): boolean => {
const permissions = userStore.getUserInfo?.authority?.permissions || ['p:aa', 'p:bb']
if (permissions.length === 0) {
return false
}
if (!value) {
throw new Error('permission.hasPermission')
}
if (!isArray(value)) {
return permissions.includes(value)
}
if (AllPermissions[0] === permissions[0]) {
return true
}
if (and) {
return !value.some((itemValue) => !permissions.includes(itemValue))
}
return (intersection(value, permissions) as string[]).length > 0
}
return {
hasPermission
}
}
2. 组件
2.1、组件 props
| prop | 类型 | 说明 |
|---|
| value | string | string[] | 权限字符串,支持数组 |
| and | boolean | 权限字符串多个情况下,and 为 true 即都需要满足,默认为 false |
| custom | boolean | 自定义权限控制逻辑,默认情况为false,没权限,组件及后代元素都不展示;如果设置true,你可以自定义控制组件具体的后代元素的展示逻辑 |
2.2、组件示例
<Permission value="p:aa">
<div>permission child text</div>
</Permission>
<Permission :value="['p:aa', 'p:bb']">
<div>permission child text</div>
</Permission>
<Permission :value="['p:bb', 'p:xx']" :and="true" :custom="true" v-slot="{ hasPermission }">
<div v-if="hasPermission">权限控制内容</div>
<ElButton type="primary" :disabled="!hasPermission">操作按钮</ElButton>
<div>非权限控制内容</div>
</Permission>
2.3、组件代码
<template>
<slot v-if="custom || hasPerm" :hasPermission="hasPerm" v-bind="attrs"></slot>
</template>
<script setup lang="ts">
import { defineProps, computed, useAttrs } from 'vue'
import { usePermission } from '@/hooks/web/usePermission'
interface IProps {
value: string | string[]
and?: boolean
custom?: boolean
}
const attrs = useAttrs()
const { hasPermission } = usePermission()
const props = withDefaults(defineProps<IProps>(), {
and: false,
custom: false
})
const hasPerm = computed(() => hasPermission(props.value, props.and))
</script>
3. 指令
3.1、示例
<div v-hasPermission="permissionValue">指令使用</div>
<div v-hasPermission="permissionValue2">不带修饰符and 指令使用</div>
<div v-hasPermission.and="permissionValue2">带修饰符and 指令使用</div>
import { ref } from 'vue'
const permissionValue = ref<string | string[]>('p:aa')
const permissionValue2 = ref<string | string[]>(['p:aa', 'p:xx'])
3.1、指令代码实现
import type { App, Directive, DirectiveBinding } from 'vue'
import { usePermission } from '@/hooks/web/usePermission'
const permissionDirective: Directive = {
mounted(el: Element, binding: DirectiveBinding<any>) {
const { hasPermission } = usePermission()
const value = binding.value
const flag = hasPermission(value, binding.modifiers.and)
if (!flag) {
el.parentNode?.removeChild(el)
}
}
}
export const setupPermissionDirective = (app: App<Element>) => {
app.directive('hasPermission', permissionDirective)
}
export default permissionDirective