1. 为何使用 react_router_config
在 React 中使用路由,一般使用react-router-dom
中的NavLink
和Route
,使用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
组件中嵌套路由组件A
和B
,B
组件中嵌套路由C
和D
,修改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_config
中renderRoutes()
函数的源码,或者也可以直接自己定义一个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/