按钮权限控制在后台管理系统中是一个比较常见的需求,下面和大家分享一下再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
不止可以在组件外获取值,还可以设置值,甚至还可以监听某个值的变化。封装完上面方法,我们可以在代码中使用。
有了全局公共方法了,为啥还要用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;
}
使用测试
有了全局公共方法了,为啥还要用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个按钮
只给用户角色分配一个新建按钮权限
然后用用户这个用户分配用户角色
登录用户帐号,进入测试测试这时候只能看到一个按钮
在给用户这个角色分配删除权限
刷新页面,再次进入测试页面,可以看到删除按钮出现了
上面方案还有可以提高开发体验的点,就是本地加了一个按钮,还要在线上配置一下,这一块其实可以写一个脚本自动把本地代码中的按钮保存到远程,这个我后面再说。
阅读量:2009
点赞量:0
收藏量:1