Nuxt3中写Vue自定义指令,以v-auth为例

背景

在后台管理系统中,常需要按钮级权限控制。在常见的访问控制RBAC 模型(用户、角色、权限)中,我们可能需要根据角色或权限来控制某个按钮的显示隐藏。

因此,我们期望使用以下方式来控制

// 单个角色
v-auth:role="'admin'"
// 多个角色
v-auth:role="['admin','manager']"
// 单个权限
v-auth:permission="'user_read'"
// 多个权限
v-auth:permission="['user_read','user_write']"

编写指令

在根目录下创建文件夹plugins,Nuxt会自动引入这个目录下的一级js文件,不需要在配置中引入。因此,我们可以创建一个auth.js文件。

// plugins/auth.js
export default defineNuxtPlugin((nuxtApp) => {
    // 不再是 import Vue from 'vue'的写法了
	nuxtApp.vueApp.directive('auth', {
        // 不用mounted,在mounted时用户权限集还是空的
		updated(el, {
			arg, // role | permission
			value, // string | array
		}) {
			if (typeof value == 'string') {
				value = [value];
			}

            // 用户信息,这里面有属性 role | permission
			const userInfo = useState('userInfo');
			const userAuth = userInfo.value?.[arg]; // 用户的角色|权限集

			if (!userAuth) {
				removeEl(el);
			}

			let hasAuth = false;
			for (const item of value) {
				if (userAuth.includes(item)) {
					// 用户拥有传入的权限
					hasAuth = true;
					break;
				}
			}

			if (!hasAuth) {
				removeEl(el);
			}
		}
	})
})

// 移除元素
const removeEl = (el) => el.parentNode && el.parentNode.removeChild(el);

使用指令

<button v-auth:role="'admin'">测试</button>

参考文档:

Vue 自定义指令

Nuxt plugins