Appearance
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
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
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
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
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
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
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
路由跳转及传参
方案一:Link 和 NavLink
NavLink可以和路由地址进行匹配,设置选中样式!!
jsx
<div className="menu">
<NavLink to="/personal/order">我的订单</NavLink>
<NavLink to="/personal/profile">我的信息</NavLink>
</div>
1
2
3
4
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
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