Twlig / issuesBlog

MIT License
3 stars 0 forks source link

react-router-middleware-plus #107

Open Twlig opened 2 years ago

Twlig commented 2 years ago

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字段,从左到右依次执行鉴权函数。

const routeConfig: RoutesMiddlewareObject[] = [
    {
        path: RouteMap.ROOT,
        element: <Home />,
        middleware: [CheckLogin, NavigateToList],
        children: [
            {
                path: RouteMap.EDIT,
                element: <Edit />,
            },
            {
                path: RouteMap.EDIT_ID,
                element: <Edit />,
            },
            {
                path: RouteMap.LISTTABLE,
                element: <ListTable />,
            },
            {
                path: RouteMap.MEANS,
                element: <Means />,
            },
        ],
    },
    {
        path: RouteMap.LOGIN,
        element: <Login />,
    },
    {
        path: RouteMap.REGISTER,
        element: <Register />,
    },
    {
        path: RouteMap.NOT_FOUND,
        element: <NotFound />,
    },
    {
        path: "*",
        element: <Navigate to={RouteMap.NOT_FOUND} replace={true} />,
    },
]

middleware是可选的,只需要在需要他的地方添加即可,middleware中的鉴权组件是从左向右依次执行的,返回嵌套的children,则通过。返回null,表示拦截。可根据实际业务需求,调整鉴权组件中的拦截逻辑。

鉴权函数

export const CheckLogin = ({ children }: any) => {
    const navigate = useNavigate()
    const params = useParams()
    const [userInfo, setUserInfo] = useState("")

    const getUserInfo = () => {
        const userInfo = localStorage.getItem("cms-token")

        if (userInfo) {
            setUserInfo(userInfo)
        } else {
            message.info("未登录,正在为您跳转到登录页...", 1)
            setTimeout(() => {
                navigate("/login")
            }, 1500)
        }
    }

    useEffect(() => {
        getUserInfo()
    }, [userInfo])

    if (!userInfo) {
        return null
    }
    return children
}

//路由重定向,如果是/,则重定向到列表页
export const NavigateToList = ({ children }: any) => {
    const navigate = useNavigate()
    const location = useLocation()
    useEffect(() => {
        if (location.pathname === "/") {
            navigate("/listtable")
        }
    }, [location.pathname])
    return children
}

渲染

config.tsx

index.tsx

import Routes from "./config"
export default () => {
    return (
        <BrowserRouter>
            <Routes />
        </BrowserRouter>
    )
}

参考文章