[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:addin 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 Authoritycomponent?

<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>

 

posted @ 2024-11-19 15:38  Zhentiw  阅读(2)  评论(0编辑  收藏  举报