路由配置
安装
npm install react-router-dom
配置
// index.js
import { BrowserRouter, Route } from 'react-router-dom'
ReactDOM.render(
<App />,
document.getElementById('root')
)
// App.js
// 这里引入了自定义组件AppHeader和AppFooter
import React, { Component, Fragment } from 'react'
import { Route, Redirect, Switch } from 'react-router-dom'
import { routes } from './router'
import AppHeader from './components/app-header'
import AppFooter from './components/app-footer'
class App extends Component {
render() {
return (
<BrowserRouter>
<Switch>
{
routes.map(item => {
if (item.children && item.children.length) {
// 内容区页面
return (
<Fragment key={item.path}>
<div className="app-content">
<AppHeader {...this.props}></AppHeader>
<main>
<Switch>
{
item.children.map(child => {
return (
<Fragment key={child.path}>
<Route path={child.path} component={child.component}></Route>
<Redirect exact from={item.path} to={item.children[0].path}></Redirect>
</Fragment>
)
})
}
</Switch>
</main>
<AppFooter></AppFooter>
</div>
</Fragment>
)
} else {
// 全局页面(包括登录、404、403等)
return (
<Route key={item.path} path={item.path} component={item.component}></Route>
)
}
})
}
<Redirect exact from="/" to="/main/home"></Redirect>
<Redirect to="/404"></Redirect>
</Switch>
</BrowserRouter>
)
}
}
export default App
代码太长了哈,是不是又懒得看了,大致思路就是:如果是登录这种全屏页面就直接
<Route path="xxx" component="xxx"><Route>
否则页面有头信息和尾信息,路由内容需要放在中间内容区,同时,有下级菜单的需要默认redirect
到下级菜单的第一个菜单
路由信息如下
// router.js
const navs = [
{
path: '/main/home',
component: Home,
navText: '首页'
},
{
path: '/main/product',
navText: '产品',
children: [
{
path: '/main/product/view',
component: ProductView,
navText: '概览'
}
]
}
]
/* 路由 */
const routes = [
{
path: '/login',
component: Login
},
{
path: '/main',
component: Main,
children: navs
},
{
path: '/404',
component: NotFound
}
]
内容区如下
/main
下面有子菜单,所以直接定位到/main/home
,也就是main下面的第一个菜单。
this.props为空
因为导航我们是写在组件AppHeader
中的,当点击菜单的时候需要进行路由跳转,需要用到this.props.history
,但是发现this.props
是{}
,开始以为是在App.js
中传入到组件中
<AppHeader {...this.props}></AppHeader>
还是为空,因为在App.js
中也是空
查看了很多资料,发现:
只有通过Route组件渲染的组件,才能在this.ptops上找到history对象
解决方法1
我们想要访问this.props.history
的组件上使用withRouter
// app-header.js
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
class AppHeader extends Component {
...
}
export default withRouter(AppHeader)
解决方法2
就是直接在最外部让App.js
有这个对象,然后在内部的组件想用就直接由App.js
中往下传
// index.js
ReactDOM.render(
<BrowserRouter>
<Route component={App}></Route>
</BrowserRouter>,
document.getElementById('root'))
// App.js
class App extends Component {
render() {
return (
<Switch>
...
</Switch>
)
}
}
这里为止,其实就是将之前写在App.js
中的BrowserRouter
,移到index.js
中,这样App.js
中就有this.props.history
对象了,此时往AppHeader
组件中传入
// App.js
<AppHeader {...this.props}></AppHeader>
注意,这里的传值一定要写,不然只有App.js
中有,下面的子组件还是没有history
这个对象。