React 集中式路由管理+路由鉴权

1. 为何使用 react_router_config

在 React 中使用路由,一般使用react-router-dom中的NavLinkRoute,使用NavLink编写路由链接,使用Route注册路由:

import { NavLink, Route } from 'react-router-dom';
...

{/* 路由链接 */}
<NavLink to="/home">Home</NavLink>
<NavLink to="/about">About</NavLink>

{/* 注册路由 */}
<Route path="/home" component={Home} />
<Route path="/about" component={About} />

注册路由部分写在相应的组件中,但一旦路由组件过多,路由嵌套关系复杂,就会很容易搞清楚路由组件之间的关系。

react_router_config可以很好地解决这个问题,react_router_config将所有的路由注册写在同一个.js文件中,各个路由中间的嵌套关系也能清晰地得到,这对于复杂的路由管理来说,十分方便。

2. react_router_config 基本使用

首先安装react_router_config库。

yarn add react_router_config

在项目根目录下创建router.js文件,将所需的路由数组形式,并向外暴露:

import Home from './components/Home';
import User from './components/User';

const routes = [
    {
        path: '/home',
        component: Home,
    },
    {
        path: '/user',
        component: User,
    },
];

export default routes;

需要开启路由的组件:

import React, { Component } from 'react';
import { renderRoutes } from 'react-router-config';
import { NavLink } from 'react-router-dom';
import routes from './router.js';

export default class App extends Component {
    render() {
        return (
            <div>
                {/* 路由链接 */}
                <NavLink to="/home">Home</NavLink>
                <NavLink to="/user">User</NavLink>

                {/* 使用react-router-config中的renderRoutes方法 */}
                {renderRoutes(routes)}
            </div>
        );
    }
}

这样,就能够实现路由的基本功能了。

3. 嵌套路由

User组件中嵌套路由组件ABB组件中嵌套路由CD,修改router.js文件,子路由通过children继续定义下去即可:

import Home from './components/Home';
import User from './components/User';
import A from './components/User/A';
import B from './components/User/B';
import C from './components/User/B/C';
import D from './components/User/B/D';

const routes = [
    {
        path: '/home',
        component: Home,
    },
    {
        path: '/user',
        component: User,
        children: [
            {
                path: '/user/a',
                component: A,
            },
            {
                path: '/user/b',
                component: B,
                children: [
                    {
                        path: '/user/b/c',
                        component: C,
                    },
                    {
                        path: '/user/b/d',
                        component: D,
                    },
                ],
            },
        ],
    },
];

export default routes;

User组件:

import React, { Component } from 'react';
import { renderRoutes } from 'react-router-config';
import { NavLink } from 'react-router-dom';

export default class User extends Component {
    componentDidMount() {
        console.log(this.props);
    }
    render() {
        return (
            <div>
                User <hr />
                <NavLink to="/user/a">A</NavLink>
                <NavLink to="/user/b">B</NavLink>

                {/* 需要用props传递嵌套的组件 */}
                {renderRoutes(this.props.route.children)}
            </div>
        );
    }
}

这里写了一个componentDidMount()勾子,看一下组件挂载后打印的内容:

可以看到,可以通过this.props.route.children得到子路由的注册信息,所以在使用renderRoutes方法时,需要传递this.props.route.children

B组件:

import React, { Component } from 'react';
import { renderRoutes } from 'react-router-config';
import { NavLink } from 'react-router-dom';

export default class B extends Component {
    render() {
        return (
            <div>
                BBB
                <hr />
                <NavLink to="/user/b/c">C</NavLink>
                <NavLink to="/user/b/d">D</NavLink>
                {renderRoutes(this.props.route.children)}
            </div>
        );
    }
}

4. 路由鉴权

有时候一个组件并不希望所有用户都能直接访问到,仅让登录过的用户可以进行访问,这时候就需要路由鉴权。通过判断的条件,来返回指定的路由组件。

修改react_router_configrenderRoutes()函数的源码,或者也可以直接自己定义一个renderRoutes()

import React from 'react';
import { Route, Redirect, Switch } from 'react-router-dom';

const renderRoutes = (routes, authed, authPath = '/login', extraProps = {}, switchProps = {}) =>
    routes ? (
        <Switch {...switchProps}>
            {routes.map((route, i) => (
                <Route
                    key={route.key || i}
                    path={route.path}
                    exact={route.exact}
                    strict={route.strict}
                    render={props => {
                        if (!route.requiresAuth || authed || route.path === authPath) {
                            return <route.component {...props} {...extraProps} route={route} />;
                        }
                        return (
                            <Redirect
                                to={{ pathname: authPath, state: { from: props.location } }}
                            />
                        );
                    }}
                />
            ))}
        </Switch>
    ) : null;

export default renderRoutes;

User组件不希望被未登录的用户访问到,修改User组件:

import React, { Component } from 'react';
// import { renderRoutes } from 'react-router-config';
// 引入自己的renderRoutes
import renderRoutes from './utils/renderRoutes';
import { NavLink } from 'react-router-dom';
import routes from './router.js';

const authed = false; // false表示未登录
const authPath = '/home'; // 需要跳转到的路径

export default class App extends Component {
    render() {
        return (
            <div>
                {/* 路由链接 */}
                <NavLink to="/home">Home</NavLink>
                <NavLink to="/user">User</NavLink>

                {/* {renderRoutes(routes)} */}
                {renderRoutes(routes, authed, authPath)}
            </div>
        );
    }
}

同时,还需要修改router.js文件的内容,在需要权限才能访问的地方加上requiresAuth: true,其他加上requiresAuth: false即可。

import Home from './components/Home';
import User from './components/User';
import A from './components/User/A';
import B from './components/User/B';
import C from './components/User/B/C';
import D from './components/User/B/D';

const routes = [
    {
        path: '/home',
        component: Home,
        requiresAuth: false,
    },
    {
        path: '/user',
        component: User,
        requiresAuth: true,
        // requiresAuth: false,
        children: [
            {
                path: '/user/a',
                component: A,
                requiresAuth: false,
            },
            {
                path: '/user/b',
                component: B,
                // requiresAuth: false,
                requiresAuth: true,
                children: [
                    {
                        path: '/user/b/c',
                        component: C,
                        requiresAuth: false,
                    },
                    {
                        path: '/user/b/d',
                        component: D,
                        requiresAuth: false,
                    },
                ],
            },
        ],
    },
];

export default routes;

这样,当用户未登录时,若访问/user,会自动跳转回/home


📘📘欢迎在我的博客上访问:
https://lzxjack.top/

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

火星飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值