大多數前端開發者在開發應用時,習慣了在一個路由配置文件中大量的引入組件和配置組件,但當路由多了,就會變得不可維護,尤爲在pc端比較明顯,可能涉及到10+的業務模塊,每一個業務模塊都涉及了3-5個路由地址,甚至更多。所以按照業務拆分路由是咱們下降複雜度的必然方式。
備註:本文分享的是你的router使用的爲react-router這個庫,版本3.2.1javascript
缺點:當分業務以後,每一個業務都有不少子路由,而且由於對應的組件通常都是不一樣的,要都維護在一個文件中,文件會比較大,不方便對應和查看。前端
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;
目錄結構:src目錄下新建routers文件夾java
--src
----routers
------index.js
------feature1.js
------feature2.js
------feature3.js
----index.jsreact
示意圖以下:git
返回一個標準的json結構的路由對象,除了標準的path,component,你還能夠加入一些其餘想加的屬性,用於應用的功能加強,好比name用於顯示這一級的頁面路由名稱,icon用於這個路由的圖標標識,meta用於記錄一些路由的元信息等。github
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實現無限的子路由地址json
這樣,在咱們的主文件中,就須要引入拆分以後的各個子路由。而後寫一個解析json配置生成route的方法。segmentfault
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這個庫呢?緣由有:微信
1 這個庫其實有特定的react-router的版本依賴,但你的項目很是可能不是這個版本。那麼就會致使兩個方向的思考:是換react-router的版本麼?但這樣會致使項目中有些組件不能用了,好比<Link>;若是不換呢,這個庫就不能用,報錯須要的Switch組件沒有。
2 其實就結果來看,這個根據json生成<Router>的功能也比較簡單,本身實現也是沒有難度的,並且還能夠追加本身想要的其餘功能,由於咱們在每一個route中均可以根據傳入的對象的某些屬性自定義render,這位應用的強化和自定義留下了更多空間。
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/5a30ce...
微信:csnikey,或者掃碼加我
達摩空間訂閱號:damo_kongjian,或者掃描下面的二維碼