专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

使用黑科技实现前端按钮权限控制,太优雅了

ins518 2025-01-15 13:57:54 技术文章 30 ℃ 0 评论

前言

按钮权限控制在后台管理系统中是一个比较常见的需求,下面和大家分享一下再react中常见的几种实现方式,不过最想分享的还是后面的黑科技方案。

实现添加按钮权限功能

  • 改造上一篇文章中添加菜单的表单,添加一个按钮类型菜单。
  • 这里权限代码建议页面路由:按钮类型格式,保证全局唯一。
  • 改造菜单模型,添加权限代码字段

常见前端按钮权限控制实现方案

前言

从用户信息中获取按钮菜单,把authCode取出来存到全局用户信息中。

封装判断权限全局方法

// src/utils/auth.ts
import {useUserStore} from '@/stores/global/user';

/**
* 判断是否有权限
* @param authCode 权限代码
* @returns
*/
export const isAuth = (authCode: string) => {
if (!authCode) return false;
// 从全局数据中获取当前用户按钮权限列表
const {currentUser} = useUserStore.getState();
  
const {authList = []} = currentUser || {};
// 判断传进来权限代码是否存在权限列表中
return authList.includes(authCode);
};

这里使用zustand做状态存储太爽了,可以直接在组件外优雅的获取全局数据,以前使用redux的时候,在组件外获取全局值还是挺麻烦的。zustand不止可以在组件外获取值,还可以设置值,甚至还可以监听某个值的变化。

封装完上面方法,我们可以在代码中使用。

封装权限组件

// src/components/auth/auth.tsx
import { isAuth } from '@/utils/auth';
import React, { FC } from 'react';

const Auth: FC<{ authCode: string, children: React.ReactElement }> = ({
authCode,
children,
}) => {
  
if (isAuth(authCode)) {
return children;
}
  
return null;
}

export default Auth;

在代码使用

封装权限hooks

有了全局公共方法了,为啥还要用hooks。如果直接在方法体里面使用方法,每次组件渲染的时候都会执行一下这个方法,如果权限比较多的话,可能会有性能问题。我们封装一个hooks,借助useMemo在authCode不变的时候,不用重新执行判断权限的方法了。

// src/hooks/use-auth/index.tsx
import { useUserStore } from '@/stores/global/user';
import { isAuth } from '@/utils/auth';
import { useMemo } from 'react';

export const useAuth = (authCode: string) => {
const { currentUser } = useUserStore();
  
const auth = useMemo(() => {
return isAuth(authCode);
}, [authCode, currentUser?.authList]);
return auth;
}

使用测试

封装高阶组件

// src/components/with-auth/index.tsx
import { isAuth } from '@/utils/auth';

export function withAuth(authCode: string) {
return function (Component: any) {
return function (props: any) {
return isAuth(authCode) ? <Component {...props}></Component> : null;
}
}
}

使用测试

使用黑科技实现按钮权限控制

背景

说是黑科技也不算是黑科技,只是在react中算是黑科技,就是通过类似于vue的指令来实现组件权限控制。在vue中实现指令很简单,但是react中不支持自定义指令。我前面写了一篇在react中自定义类似于vue指令的文章,我自己写了一个库,可以在react中使用一些vue指令,并且还可以自定义指令,大家可以先去看下,本文说的黑科技就是基于指令实现的,原理就是重新react的createElement方法。

安装依赖,并在项目中配置

pnpm i @dbfu/react-directive

修改tsconfig.json文件

在vite配置中安装插件

然后我们就能快乐的在react代码中使用vue指令了

自定义指令

import { isAuth } from '@/utils/auth';
import { directive } from "@dbfu/react-directive/directive";

export const registerAuthDirective = () => {
directive('v-auth', {
create: (authCode: string) => {
return isAuth(authCode)
},
})
}

自定义指令前面文章中有说明,我这里就不详细说了。

在App.tsx文件中注册指令

在代码中使用

在任意组件中都可以使用这个指令,不用引入其他依赖,简直太优雅了。

测试

在测试页面中创建4个按钮

在菜单中配置4个按钮

只给用户角色分配一个新建按钮权限

然后用用户这个用户分配用户角色

登录用户帐号,进入测试测试这时候只能看到一个按钮

在给用户这个角色分配删除权限

刷新页面,再次进入测试页面,可以看到删除按钮出现了

总结

上面方案还有可以提高开发体验的点,就是本地加了一个按钮,还要在线上配置一下,这一块其实可以写一个脚本自动把本地代码中的按钮保存到远程,这个我后面再说。

项目体验地址:https://fluxyadmin.cn/user/login

前端仓库地址:https://github.com/dbfu/fluxy-admin-web

后端仓库地址:https://github.com/dbfu/fluxy-admin-server

作者:前端小付
链接:https://juejin.cn/post/7254123931246772280

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表