往期回顾
前端框架搭建——从零开始搭建一个高颜值后台管理系统全栈框架(一)
后端框架搭建——从零开始搭建一个高颜值后台管理系统全栈框架(二)
实现登录功能jwt or token+redis?——从零开始搭建一个高颜值后台管理系统全栈框架(三)
封装axios,让请求变得丝滑——从零开始搭建一个高颜值后台管理系统全栈框架(四)
实现前后端全自动化部署,解放你的双手。——从零开始搭建一个高颜值后台管理系统全栈框架(五)
雪花算法,附件方案,邮箱验证,修改密码。——从零开始搭建一个高颜值后台管理系统全栈框架(六)
基于react-router v6实现动态菜单、动态路由。内含vue动态路由实现。——从零开始搭建一个高颜值后台管理系统全栈框架(七)
前言
按钮权限控制在后台管理系统中是一个比较常见的需求,下面和大家分享一下再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个按钮
只给用户角色分配一个新建按钮权限
然后用用户这个用户分配用户角色
登录用户帐号,进入测试测试这时候只能看到一个按钮
在给用户这个角色分配删除权限
刷新页面,再次进入测试页面,可以看到删除按钮出现了
总结
上面方案还有可以提高开发体验的点,就是本地加了一个按钮,还要在线上配置一下,这一块其实可以写一个脚本自动把本地代码中的按钮保存到远程,这个我后面再说。
项目体验地址:fluxyadmin.cn/user/login
前端仓库地址:github.com/dbfu/fluxy-…
后端仓库地址:github.com/dbfu/fluxy-…