持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情
一、你的苦恼~~
你还在为react-router的路由权限控制而烦恼吗?
你还在翻遍了社区react路由权限相关文章发现都是V4、V5版本的而烦恼吗?
你还在为自行适配react-router v6版本的权限步骤繁杂,多重鉴权逻辑嵌套而烦恼吗?
他来了!他来了!他带着礼物走来了!react-router-middleware-plus专为解决你的烦恼而生!
二、react-router-middleware-plus
react-router-middleware-plus是基于react-router v6的路由权限配置开源库,引入中间件middleware的概念,零成本式路由权限解决方案。
midleware定义为中间件的概念,是包含了一个或多个用户自定义的Auth Component鉴权组件数组,react-router-middle-plus会在内部维护一个嵌套高阶组件,在页面路由加载时,会依次执行中间件中的Auth Component。如果你想拦截路由在Auth Component中直接返回null即可,如果允许通过返回children即可。
middleware处理流程图:
以业务流程举例说明:
| 组件 | 权限 | 描述 |
|---|---|---|
| Home | 无 | 首页 |
| Login | 无 | 登录页面 |
| Admin | 1. 登录状态 2. 管理员 | 管理员页面 |
路由组件配置声明:
如何来配置中间件呢,非常的简单,只需要在原有定义路由的地方,增加middleware参数即可。
/**
* @description 路由配置
*
*/
const routes = [
{
path: '/',
key: 'index',
element: <App></App>,
children: [
{
index: true,
key: 'home',
element: <Home></Home>
},
{
path: 'admin',
key: 'admin',
// 中间件,允许配置一个或多个
middleware: [
checkLogin,
checkRole,
// auth3
// ...
],
element: <Admin></Admin>
}
]
},
{
path: '/login',
key: 'login',
element: <Login></Login>
},
]
middleware是可选的,只需要在需要他的地方添加即可,middleware中的鉴权组件是从左向右依次执行的,返回嵌套的children,则通过。返回null,表示拦截。可根据实际业务需求,调整鉴权组件中的拦截逻辑
三、快速开始
-
安装依赖
yarn add react-router-middleware-plus -DOR
npm install react-router-middleware-plus -
配置路由
/** * @file: router.tsx 路由配置组件 * @author: huxiaoshuai */ import React from 'react'; import { useNavigate } from 'react-router-dom'; import { ReactRouterMiddleware, useMiddlewareRoutes } from 'react-router-middleware-plus'; import App from './App'; import Home from './home'; import Login from './login'; import Admin from './admin'; /** * @method getUserInfoApi * @description 模拟后端接口,返回用户登录数据 */ const getUserInfoApi: any = () => { return new Promise((resolve, reject) => { setTimeout(() => { // 已登录 resolve({ username: '胡小帅' }) // 未登录 // resolve(null) }, 100) }) } /** * @method CheckLogin * @description 鉴权-登录 */ const CheckLogin = ({children}: any) => { const navigate = useNavigate(); const params = useParams(); const [userInfo, setUserInfo] = useState(null); const getUserInfo = async () => { const userInfo = await getUserInfoApi(); if (userInfo) { setUserInfo(userInfo) } else { navigate('/login') } } useEffect(() => { getUserInfo() }, []) if (!userInfo) { return null; } return children } /** * @method checkRole * @description 鉴权-用户角色 */ const CheckRole = ({children}: any) => { const navigate = useNavigate(); // 根据自己的页面,判断处理,async/await异步拉取用户数据即可。 const isAdmin = localStorage.getItem('role') === 'admin'; useEffect(() => { if (!isAdmin) { navigate('/', { replace: true }) } }, [isAdmin]) // 通过鉴权 return isAdmin ? children : null; } export default function Router () { // 定义路由配置,与react-router-dom是一致的,只是新增了middleware参数,可选 // middleware中的鉴权逻辑callback,是从左向右依次调用的,遇到第一个返回false的callback会拦截路由组件的渲染,走callback中用户自定义逻辑 /** * @description 路由配置 * */ const routes = [ { path: '/', key: 'index', element: <App></App>, children: [ { index: true, key: 'home', element: <Home></Home> }, { path: 'admin', key: 'admin', // middleware中Auth Component从左到右依次执行 middleware: [CheckLogin, CheckRole], element: <Admin></Admin> } ] }, { path: '/login', key: 'login', element: <Login></Login> }, ]; // 生成路由配置由两种方式:Component 或者是使用Hook useMiddlewareRoutes // 1. Component 渲染 // return <ReactRouterMiddleware routes={routes}></ReactRouterMiddleware>; // 2. Hook渲染 return useMiddlewareRoutes(routes); } -
渲染路由
/** * @file index.tsx 入口文件 * @author huxiaoshuai */ import React from 'react'; import ReactDOM from 'react-dom/client'; import { BrowserRouter } from 'react-router-dom'; import Router from './router'; ReactDOM.createRoot(document.getElementById('root')!).render( <BrowserRouter> <Router /> </BrowserRouter> );
对,是的,就是这么简单!就通过配置middleware,灵活搭配组合callback,在callback中自定义处理逻辑,路由权限处理问题解决了
四、Props介绍
react-router-middleware-plus在使用时和react-router-dom中的useRoutes是一致的。
| 属性 | 类型 | 描述 | 是否可选 |
|---|---|---|---|
| routes | RoutesMiddlewareObject[] | 路由配置,在RoutesObject类型上扩展了middleware属性 | 否 |
| locationArg | Partial<Location> | string | 用户传入的location对象 | 可选 |
// 1. Component 渲染
// return <ReactRouterMiddleware routes={routes}></ReactRouterMiddleware>;
// 2. Hook渲染
return useMiddlewareRoutes(routes);
五、middleware callback介绍
这里提供下类型声明,MiddlewareFunction和RoutesMiddlewareObject。
export interface MiddlewareFunction {
(): boolean
}
export interface RoutesMiddlewareObject extends RouteObject {
/**
* @description 权限处理的middleware callback[]
*
*/
middleware?: MiddlewareFunction[];
/**
* @description 子路由
*
*/
children?: RoutesMiddlewareObject[];
}
再次强调一下,如果拦截路由就在MiddlewareFunction中返回false,如果通过就是返回true。
六、求Star
如果你通过使用react-router-middleware-plus解决了路由配置鉴权问题,欢迎你点个Star。
同时非常欢迎小伙伴们提Issues和PR。