组件权限校验
按钮权限
按钮级别权限可以使用 自定义指令 来实现,全局注入自定义指令:
vue
<template>
<a-button type="primary" v-auth="true">有权限按钮</a-button>
<a-button type="primary" v-auth="false">无权限按钮</a-button>
</template>
<script setup lang="ts">
import {Button as AButton} from 'ant-design-vue'
</script>
ts
const app = createApp(App)
app.directive("auth", {
mounted: (el, binding) => {
// 类型判断,规定权限校验的值必须为 boolean 类型
// 也可以按照用户角色,判断按钮/组件是否拥有权限
if (typeof binding.value === "boolean") {
if (!binding.value) {
el.style.display = "none";
}
}
}
})
组件权限
组件的权限校验需要注意:如果用 v-auth
自定义指令控制其显示或隐藏,虽然隐藏了组件,但是组件的生命周期函数还是会执行的!
看下面的示例:
vue
<template>
<a-button type="primary" @click="handleClick">有权限按钮</a-button>
<!-- 组件没权限,已经不显示了 -->
<HelloWorld ref="helloRef" v-auth="false"/>
</template>
<script setup lang="ts">
import {ref} from "vue";
import {Button as AButton} from 'ant-design-vue'
import HelloWorld from "./components/HelloWorld.vue";
const helloRef = ref(null)
function handleClick() {
helloRef.value?.change(); // 该方法仍然会触发
}
</script>
vue
<template>
<div class="my-table">
<a-table
:columns="columns"
:data-source="data"
:pagination="false"
:bordered="true"/>
</div>
</template>
<script setup lang="ts">
import {onMounted} from "vue";
import {Table as ATable} from 'ant-design-vue'
const columns = [
{
title: '姓名',
dataIndex: 'name',
key: 'name',
align: 'center',
},
{
title: '年龄',
dataIndex: 'age',
key: 'age',
align: 'center',
}
];
const data = [
{
key: '1',
name: '王一博',
age: 32,
},
{
key: '2',
name: '陈伟霆',
age: 42,
}
];
onMounted(() => {
console.log("onMounted组件触发")
})
function change() {
console.log("change点击")
}
defineExpose({
change
})
</script>
<style scoped>
.my-table {
width: 400px;
margin-top: 10px;
}
</style>
注意
上面的示例中,虽然 v-auth="false"
表示组件没有权限已经隐藏了,但是 <HelloWorld />
中的 onMounted 生命周期和 defineExpose 暴漏的方法仍然可以被触发!
解决方案:
新增 <Authority>
组件,该组件有一个默认插槽,通过 v-if
判断插槽内容是否有权限显示。
vue
<template>
<slot v-if="hasPermission()"></slot>
</template>
<script setup lang="ts">
const props = defineProps(['auth'])
function hasPermission() {
// 权限校验工作...
return ['admin'].includes(props.auth)
}
</script>
vue
<template>
<a-button type="primary" @click="handleClick">有权限按钮</a-button>
<!-- auth属性传递当前用户角色 -->
<Authority auth="user">
<HelloWorld ref="helloRef" />
</Authority>
</template>
<script setup lang="ts">
import {ref} from "vue";
import {Button as AButton} from 'ant-design-vue'
import HelloWorld from "./components/HelloWorld.vue";
import Authority from "./components/Authority.vue";
const helloRef = ref(null)
function handleClick() {
helloRef.value?.change();
}
</script>