场景
大多数前端开发者在开发应用时,习惯了在一个路由配置文件中大量的引入组件和配置组件,但当路由多了,就会变得不可维护,尤其在pc端比较明显,可能涉及到10 的业务模块,每个业务模块都涉及了3-5个路由地址,甚至更多。因此按照业务拆分路由是我们降低复杂度的必然方式。
备注:本文分享的是你的router使用的为react-router这个库,版本3.2.1
原来的版本
缺点:当分业务之后,每个业务都有很多子路由,并且因为对应的组件一般都是不同的,要都维护在一个文件中,文件会比较大,不方便对应和查看。
function RouterConfig() {
return (
<Router history={hashHistory}>
<Route path="login" component={Login} />
<Route path="/" component={Main}>
<IndexRoute component={ApplyList} />
<Route path="index" component={Index} />
<Route path="apply-list" component={ApplyList} />
</Route>
</Router>
);
}
export default RouterConfig;
在每个feature中定义自己的路由
目录结构:src目录下新建routers文件夹
--src
----routers
------index.js
------feature1.js
------feature2.js
------feature3.js
----index.js
示意图如下:
拆分之后的顶级路由
返回一个标准的json结构的路由对象,除了标准的path,component,你还可以加入一些其他想加的属性,用于应用的功能增强,比如name用于显示这一级的页面路由名称,icon用于这个路由的图标标识,meta用于记录一些路由的元信息等。
import Main from '../layout/main';
import ApplyList from '../pages/applyList';
const Span = () => <span>345345</span>;
export default {
path: '/feature1',
name: 'feature1',
component: Main,
childRoutes: [
{
path: '1',
name: '1',
component: ApplyList,
childRoutes: [{
path: 'feature1',
name: 'feature1sdf',
component: Span,
}],
},
{ path: '2', name: '2', component: ApplyList },
],
};
备注:有子路由的组件,注意以下三点:
1 父组件的路径不能单独访问,除非设置重定向
2 父组件中设置{this.props.children},子组件的路由将在这个位置展示
3 代码中的组件每一层都可以增加嵌套childRoutes实现无限的子路由地址
主文件--index.js
这样,在我们的主文件中,就需要引入拆分之后的各个子路由。然后写一个解析json配置生成route的方法。
import React from 'react';
import { hashHistory, Router, Route } from 'react-router';
import feature1 from './feature1';
import feature2 from './feature2';
import feature3 from './feature3';
const combineRoutes = [feature1, feature2, feature3];
function renderRouterV3(routes, contextPath) {
const children = [];
const renderRouter = (item, itemContextPath) => {
let newContextPath;
if (/^\//.test(item.path)) {
newContextPath = item.path;
} else {
newContextPath = `${itemContextPath}/${item.path}`;
}
newContextPath = newContextPath.replace(/\/ /, '/');
if (item.component && item.childRoutes) {
const childRoutes = renderRouterV3(item.childRoutes, newContextPath);
children.push(<Route
key={newContextPath}
component={item.component}
>{childRoutes}
</Route>);
} else if (item.component) {
children.push(<Route key={newContextPath}
component={item.component} path={newContextPath} />);
}
};
routes.forEach(route => {
renderRouter(route, contextPath);
});
return children;
}
function RouterConfig() {
return <Router history={hashHistory}>
{renderRouterV3(combineRoutes, '/')}
</Router>;
}
export default RouterConfig;
解析:renderRouterV3 是我自己封装的一个方法,和开源库react-router-config实现的效果是一致的,基于json结构的路由配置可以实现生成对应的router配置。优点在于减少库依赖,灵活性更强,可以针对自己的需求在路由的生成以及自定义渲染上增加更多内容。
renderRouterV3的核心逻辑是:
0 内部定义一个渲染单组件方法,renderRouter,传入当前的单组件以及相对路径
1 解析一个传入的顶级路由数组
2 针对每一项,调用renderRouter
3 renderRouter内部针对每个顶级路由数组解析它的结构,如果是纯组件,直接返回router对象也是中止条件;如果发现其具有childRoutes,那么调用renderRouterV3本身,实现递归
4 方法返回生成后的route数组作为router组件的子组件
react-router-config
可能会有小伙伴问为什么不直接用react-router-config这个库呢?原因有:
1 这个库其实有特定的react-router的版本依赖,但你的项目非常可能不是这个版本。那么就会导致两个方向的思考:是换react-router的版本么?但这样会导致项目中有些组件不能用了,比如;如果不换呢,这个库就不能用,报错需要的Switch组件没有。
2 其实就结果来看,这个根据json生成
3 如果有时间,折腾下也未尝不可,不要总想着有什么需求就去找第三方库。其实类似classname这样的库,我们不一定需要。尤其在特别简单的class管理的时候。
小结
通过本文希望你能了解想拆分路由复杂度时,可以做的事情,以及如何自定义。
关于我
我是一名前端Coder,热爱分享生活与技术中的经验与心得。我是一名旅游爱好者,爱好拍摄旅途中的风景与人物。我是一名写作狂人,基本每天都有新文章产出,笔耕不辍。
个人站点
- GitHub:http://github.com/robinson90
- codepen:https://codepen.io/robinson90
- personal blog: http://damobing.com
- yuque docs: https://www.yuque.com/robinson
- juejin blog: https://juejin.im/user/5a30ce0c51882561a20a768b
个人微信号与公众号
微信:csnikey,或者扫码加我
达摩空间订阅号:damo_kongjian,或者扫描下面的二维码
来源:CSDN
作者:damobing
链接:https://blog.csdn.net/csnikey/article/details/103484602