UniApp 自定义指令实现权限控制

最近,为了方便移动办公,我在开发 UniApp 的移动端后台管理系统。在开发过程中,我发现 UniApp 本身并不直接支持类似于 Ruoyi 的 v-hasPermi 自定义指令功能。本文将介绍如何在 UniApp 中实现类似 v-hasPermi 的自定义指令功能。

其实,这个过程本质上是将指令转化为 v-if,然后交由 uni() 处理。

1. 准备工作

首先,我们需要定义一个 permission.js 文件,该文件用于判断用户是否具有某个权限。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// src/permission.js
import {useAuthStore} from "@/store/auth";

const permission = (_BR) => {
/**
* useAuthStore().roles = ['system:a:b','system:a:c'...]
*/
const roles = useAuthStore().roles // 后台获取到用户的权限,我这里使用`pinia`存储(或其他方法)。

if (_BR && typeof _BR === 'object' && _BR.length>0){
for (let i = 0; i < _BR.length; i++) {
if(!roles.includes(_BR[i]))
return false
}
return true
}
return false
}

export default permission

可以直接引用该方法并传入权限字符串来判断用户是否有该权限

2. 全局引入 permission

接下来,在项目的 main.js 中将 permission 方法全局引入:

1
2
3
4
5
6
7
8
9
10
11
12
// src/main.js

import { createSSRApp } from "vue"
import App from "./App.vue"
import permission from "@/permission"
export function createApp() {
const app = createSSRApp(App)
app.config.globalProperties.$permission = permission // 将权限判断方法添加到全局属性
return {
app
};
}

这样,你就可以在任何组件中通过 $permission 直接使用权限判断功能。

3.编写vite插件:

接下来,编写一个 Vite 插件来处理 cu-permission 属性,将其转化为 v-if。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// plugin/rollup-permission-converter.js

const rollupPermissionConverter = () => ({
name: 'rollup-permission-converter',
transform(code, id) {
if (id.endsWith('.vue')) {
const regex = /v-if="(.+?)"\s+v-if="(.+?)"/g;

// 转换 cu-permission 属性为 v-if
code = code.replace(/<[^>]+cu-permission="([^"]+)"[^>]*>/g, (match, cuPermissionValue) => {
return match.replace(`cu-permission="${cuPermissionValue}"`, `v-if="$permission(${cuPermissionValue})"`);
})
// 合并多个 v-if 条件
.replace(/<[^>]+v-if="([^"]+)"[^>]*v-if="([^"]+)"[^>]*>/g, (match, firstVIf, secondVIf) => {
const mergedVIf = `${firstVIf} && ${secondVIf}`;
return match.replace(/v-if="([^"]+)"/, `v-if="${mergedVIf}"`);
})
.replace(regex, 'v-if="$1"');
}
return code;
},
});

export default rollupPermissionConverter;

通过这个插件,我们可以将页面中使用的 cu-permission 属性转换为 Vue 的 v-if 语句,从而实现权限控制。

4. 使用自定义指令

经过插件的处理后,可以在 Vue 组件中直接使用 cu-permission 属性进行权限控制:

示例1

1
2
3
4
5
6
7
8
9
<template>
<view v-if="showDetail" cu-permission="['system:a:b']">
...
</view>
</template>

<script setup>
const showDetail = ref(false);
</script>

经过插件转译后,这段代码会变成:

1
2
3
4
5
6
7
8
9
<template>
<view v-if="showDetail && $permission(['system:a:b'])">
...
</view>
</template>

<script setup>
const showDetail = ref(false);
</script>

示例2

1
2
3
4
5
<template>
<view cu-permission="['system:a:c']">
<scroll-view>...</scroll-view>
</view>
</template>

经过插件转译后,这段代码会变成:

1
2
3
4
5
<template>
<view v-if="$permission(['system:a:c'])">
<scroll-view>...</scroll-view>
</view>
</template>

UniApp 自定义指令实现权限控制
http://example.com/2023/12/19/uniapp-permission/
作者
Donghao Ji
发布于
2023年12月19日
许可协议