Skip to content
On this page

dva中的路由配置

index.js

JavaScript
import dva from 'dva';
/*
 安装history模块「安装v4.10.1版本,不建议安装最新版本」
 $ yarn add history@4.10.1
 默认开启的就是HASH路由,如果想使用History路由,则导入createBrowserHistory!!
*/
import createHistory from 'history/createHashHistory';
const app = dva({
    // 指定路由模式
    history: createHistory()
});
...
app.router(require('./router').default);
app.start('#root');
1
2
3
4
5
6
7
8
9
10
11
12
13
14

router.js

JavaScript
/* 
dva/router中包含了react-router-dom v5版本中所有API,以及react-router-redux中的的API 
*/
import React from 'react';
import { Router, Route, Switch, Redirect } from 'dva/router';
import Vote from './routes/Vote';
import Demo from './routes/Demo';
import Personal from './routes/Personal';

/* ANTD */
...

const RouterConfig = function RouterConfig({ history }) {
  return <ConfigProvider locale={zhCN}>
    <Router history={history}>
      <Switch>
        <Route path="/" exact component={Vote} />
        <Route path="/demo" component={Demo} />
        <Route path="/personal" component={Personal} />
        <Redirect to="/" />
      </Switch>
    </Router>
  </ConfigProvider>;
}
export default RouterConfig;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

路由懒加载

JavaScript
import React from 'react';
import { Router, Route, Switch, Redirect } from 'dva/router';
import Vote from './routes/Vote';
import dynamic from 'dva/dynamic'; //实现动态组件的API

/* ANTD */
...

const RouterConfig = function RouterConfig({ history, app }) {
  /* 异步组件 */
  const DemoAsync = dynamic({
    app,
    models: () => [
      import(/* webpackChunkName:"demo" */ './models/demoModel')
    ],
    component: () => import(/* webpackChunkName:"demo" */ './routes/Demo')
  });
  const PersonalAsync = dynamic({
    app,
    models: () => [
      import(/* webpackChunkName:"personal" */ './models/personalModel')
    ],
    component: () => import(/* webpackChunkName:"personal" */ './routes/Personal')
  });

  return <ConfigProvider locale={zhCN}>
    <Router history={history}>
      <Switch>
        <Route path="/" exact component={Vote} />
        <Route path="/demo" component={DemoAsync} />
        <Route path="/personal" component={PersonalAsync} />
        <Redirect to="/" />
      </Switch>
    </Router>
  </ConfigProvider>;
}
export default RouterConfig;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

配置路由表和二级路由 routerRoutes.js 路由表

JavaScript
import Vote from './routes/Vote';
import dynamic from 'dva/dynamic';
/* 配置路由懒加载 */
const lazy = function lazy(models, component) {
    return dynamic({
        app: window.app, //在入口处挂载到window上
        models,
        component
    });
};

const routes = [{
    path: '/',
    exact: true,
    component: Vote,
    meta: { title: '首页' }
}, {
    path: '/demo',
    component: lazy(
        () => [import(/* webpackChunkName:"demo" */ './models/demoModel')],
        () => import(/* webpackChunkName:"demo" */ './routes/Demo')
    ),
    meta: { title: '测试页' }
}, {
    path: '/personal',
    component: lazy(
        () => [import(/* webpackChunkName:"personal" */ './models/personalModel')],
        () => import(/* webpackChunkName:"personal" */ './routes/Personal')
    ),
    meta: { title: '个人中心' },
    /* 二级路由 */
    children: [{
        redirect: true,
        exact: true,
        from: '/personal',
        to: '/personal/order'
    }, {
        path: '/personal/order',
        component: lazy(
            () => [],
            () => import(/* webpackChunkName:"personal" */ './routes/personal/MyOrder')
        ),
        meta: { title: '个人中心-我的订单' }
    }, {
        path: '/personal/profile',
        component: lazy(
            () => [],
            () => import(/* webpackChunkName:"personal" */ './routes/personal/MyProfile')
        ),
        meta: { title: '个人中心-我的信息' }
    }]
}, {
    redirect: true,
    to: '/'
}];
export default routes;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

router.js

jsx
import React from 'react';
import { Router, Route, Switch, Redirect } from 'dva/router';
import routes from './routerRoutes';
/* ANTD */
...
/* 动态创建路由 */
const createRoute = function createRoute(routes) {
  return <Switch>
    {routes.map((item, index) => {
      let { redirect, from, to, exact, path, meta, component: Component } = item,
        config = {};
      // 重定向
      if (redirect) {
        config = { to };
        if (from) config.from = from;
        if (exact) config.exact = exact;
        return <Redirect {...config} key={index} />;
      }
      // 正常路由
      config = { path };
      if (exact) config.exact = exact;
      return <Route {...config} key={index}
        render={(props) => {
          // 修改标题
          let { title = '' } = meta;
          document.title = `${title}-珠峰培训React`;
          return <Component {...props} />;
        }} />;
    })}
  </Switch>;
};
/* 一级路由 */
const RouterConfig = function RouterConfig({ history }) {
  return <ConfigProvider locale={zhCN}>
    <Router history={history}>
      {createRoute(routes)}
    </Router>
  </ConfigProvider>;
};
/* 二级路由 */
export const childrenRouter = function childrenRouter(path) {
  let item = routes.find(item => item.path === path),
    children;
  if (item) children = item.children;
  if (!children) return null;
  return createRoute(children);
};
export default RouterConfig;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

index.js

JavaScript
import dva from 'dva';
import createHistory from 'history/createHashHistory';
import voteModel from './models/voteModel';
// 1. Initialize
const app = dva({
    history: createHistory()
});
window.app = app;
// 2. Plugins
// app.use({});
// 3. Model
app.model(voteModel);
// 4. Router
app.router(require('./router').default);
// 5. Start
app.start('#root');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Personal.jsx

jsx
import React from "react";
import { NavLink } from 'dva/router';
import styled from "styled-components";
import { childrenRouter } from '../router';
/* 样式处理 */
const PersonalBox = styled.div`
    ...
`;
const Personal = function Personal() {
    return <PersonalBox>
        <div className="menu">
            <NavLink to="/personal/order">我的订单</NavLink>
            <NavLink to="/personal/profile">我的信息</NavLink>
        </div>
        <div className="content">
            {childrenRouter('/personal')}
        </div>
    </PersonalBox>;
};
export default Personal;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

路由跳转及传参

NavLink可以和路由地址进行匹配,设置选中样式!!

jsx
<div className="menu">
    <NavLink to="/personal/order">我的订单</NavLink>
    <NavLink to="/personal/profile">我的信息</NavLink>
</div>
1
2
3
4

方案二:编程式导航

jsx
import React from "react";
import { routerRedux } from 'dva/router';
import { connect } from 'dva';

const MyOrder = function MyOrder(props) {
    /* 
    基于路由匹配的组件,其属性中包含:history、location、match!
      其中history就是实现路由跳转的
        + push
        + replace
        + go
        + goBack
        + goForward
      如果组件不是基于路由匹配的,可以基于 withRouter 高阶函数处理即可!!
    */
    let { history, dispatch } = props;
    return <div className="myOrderBox">
        我的订单
        <button onClick={() => {
            // history.push('/personal/profile');

            /* 
             routerRedux 也可以实现路由跳转,语法和history类似
             好处:可以在Effects中基于 yield 实现路由跳转
                // Inside Effects
                yield put(routerRedux.push('/logout'));

                // Outside Effects
                dispatch(routerRedux.push('/logout'));
             */
            dispatch(routerRedux.push('/personal/profile'));
        }}>跳转</button>
    </div>;
};
export default connect()(MyOrder);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
沪ICP备20006251号-1