手写一个根据目录自动生成的路由

一、起因

最近研究了一下阿里dva的quickstart,其中路由配置是手动添加。
如下,先将要显示的页面导入router.js,然后配置 .
其中path="/products"是配置的路由地址,component={Products}为这个地址显示的页面。

import React from 'react';
import { Router, Switch, Route } from 'dva/router';
import Products from './routes/Products';
import Example from './components/Example';

function RouterConfig({ history }) {
  return (
    <Router history={history}>
      <Switch>
        <Route path="/" exact component={Example}/>
        <Route path="/products" exact component={Products}/>
      </Switch>
    </Router>
  );
}

module.exports = RouterConfig;

二、思索

想了一下,或许可以让路由自动生成,就不用每个都手动导入。
我的实现思路是,写一个配置文件router.config.js,让他自动生成路由地址及指向的模块。
改写后的router.js根据读取到的信息生成,而不再写死。改写后的router.js代码如下

import React from 'react';
import { Router, Route, IndexRoute } from 'dva/router';
import RouterArray from './router.config';
import NotFound from './routes/404';

const loadRoutes = (rts) => {
  const arr = [];
  rts.forEach((route, idx) => {
    if (route.children) {
      arr.push(
        route.component ?
          <Route key={route.path + idx} path={route.path} component={route.component}>
            {loadRoutes(route.children)}
          </Route>
          :
          <Route key={route.path + idx} path={route.path}>
            {loadRoutes(route.children)}
          </Route>
          ,
      );
    } else if (route.index === true) {
      arr.push(<IndexRoute key={idx} component={route.component} />);
    } else {
      arr.push(<Route key={route.path + idx} path={route.path} component={route.component} />);
    }
  });
  return arr;
};

function RouterConfig({ history }) {
  const routes = loadRoutes(RouterArray);
  routes.push(<Route key="404" path="/*" component={NotFound} />);
  return (
    <Router history={history}>
      { routes }
    </Router>
  );
}

export default RouterConfig;

其中的RouterArray是配置文件router.config.js根据目录读取到的信息,传给router.js,然后生成路由。router.config.js的代码如下:

import App from './routes/Main';

const routerConfig = [];
const files = require.context('./routes', true, /route.js$/);
files.keys().filter(i => i.includes('/route.js') || i.includes('/app.route.js')).forEach((key) => {
  const m = files(key);
  const idx = routerConfig.findIndex(it => it.path === m.path);
  if (idx > -1) {
    routerConfig[idx].children = routerConfig[idx].children.concat(m.children);
  } else {
    routerConfig.push(m);
  }
});
// 设置根路由组件
const idx = routerConfig.findIndex(it => it.path === '/');
if (idx > -1) {
  routerConfig[idx].component = App;
}
export default routerConfig;

三、测试效果

完成代码改造后写了几个页面测试效果,分别是Test,对应代码index.js;SecondPage对应代码SecondPage.js和404error页面。分别输入下面地址即可查看:
http://localhost:9000/#/Test
http://localhost:9000/#/SecondPage
http://localhost:9000/#/404

其代码结构如下:
在这里插入图片描述

四、项目代码

https://github.com/lisiqil/router

欢迎大家下载代码阅读,如有什么错误欢迎指正。

原创文章 19 获赞 16 访问量 2446

猜你喜欢

转载自blog.csdn.net/qq_42778289/article/details/103266648