[Vue] Component authority controls
For component level authority controls, we need to find a common partten so that we can extract a common component to handle the permission control in order to avoid directly modfiying component itself.
For example, we have following user authority level:
sys:user:view
sys:user:update
sys:user:delete
sys:user:add
And we want current user should have authority sys:user:add
in order to show "Add user" button
<template>
<div class="container">
<div class="btn-container">
<Authority permission="sys:user:add">
<a-button type="primary">新增用户</a-button>
</Authority>
<a-button type="primary">查询用户</a-button>
<a-button type="primary">修改用户</a-button>
<a-button type="primary" danger>删除用户</a-button>
<a-button type="primary" danger>禁用用户</a-button>
</div>
</div>
</template>
For combine multi authorities:
<Authority :permission="['sys:user:view', 'sys:user:update']">
<a-button type="primary" danger>禁用用户</a-button>
</Authority>
Both are just controling show / hide UI component, which is still easy to do.
If we don't just want to show/hide component, we want to disable component based on user authority, we need to use template
<Authority>
<template #default="{ userPermissions }">
<a-button
:disabled="!userPermissions.includes('sys:user:add')"
type="primary"
>
新增用户
</a-button>
</template>
</Authority>
<!--
<template #default>:
This declares the default slot for the Authority component.
In Vue 3, the shorthand #default is equivalent to v-slot:default.
{ userPermissions }:
The braces ({}) indicate slot props being destructured.
The parent component (Authority) is passing a prop named userPermissions to the slot.
By destructuring it, you can directly access userPermissions without needing slotProps.userPermissions.
-->
How to write Authority
component?
<template>
<slot v-if="showSlot" :userPermissions="permissions"></slot>
</template>
<script setup>
import { computed } from 'vue';
import { useAuth } from './useAuth';
const props = defineProps({
permission: {
type: [String, Array],
},
});
const { permissions } = useAuth();
const showSlot = computed(() => {
if (!props.permission) {
// No permissions required, show slot
return true;
}
if (Array.isArray(props.permission)) {
// Check if all required permissions exist
return props.permission.every((p) => permissions.value.includes(p));
} else {
// Check if single required permission exists
return permissions.value.includes(props.permission);
}
});
</script>