react中的路由管理 REACT-ROUTER-DOM(第四代版本开始) - HASH路由(地址丑)
react-router-dom实现SPA单页面应用
yarn add react-router-dom
REACT-ROUTER提供了两种路由方式:
1.Brower-router(基于H5中的history-api完成)(需要服务器对404页面做处理:如果请求的页面不存在,让其渲染首页的内容)
- http://www.xxx.com/user
- http://www.xxx.com/user/singin
2.Hash-router(基于HASH值处理的)
- http://www.xxx.com/#/user
- http://www.xxx.com/#/user/singin
如果项目是单纯静态页面展示(数据绑定是由客户端完成的),一般使用hash-router完成;如果当前的项目有些内容是需要后台完成,我们尽量使用brower-router,因为hash值不太容易和服务器端产生关联;
基础使用
import React, { Component } from 'react';
import { HashRouter, BrowserRouter, Switch, Route, Redirect } from 'react-router-dom';
import Custom from './Custom';
import System from './System';
import Error from './Error';
class App extends Component {
render() {
return <>
<header style={{ background: 'lightblue' }}>
<a href="">客户管理</a>
<a href="">系统设置</a>
</header>
<main>
<HashRouter>
<Switch>
{/* <Route path='/' exact component={Custom} /> */}
<Redirect from='/' exact to='/custom' />
<Route path='/custom' component={Custom} />
<Route path='/system' component={System} />
{/* 做一个404处理:以上规则都不符合 */}
{/* <Redirect to='/custom' /> */}
<Route path='*' component={Error} />
</Switch>
</HashRouter>
</main>
</>;
}
}
export default App;
- HashRouter:HASH路由容器
- Route:设置路规则
+ 路由特点一:
不管当前规则是否匹配,依然会向下匹配查找,而我们期望的是某一条规则匹配后,不再向下匹配(vue的路由天生就这样) => react路由可以把路由规则基于包裹起来即可
+ 路由特点二:
默认路由匹配的规则是不精准也不严格的,我们可以给规则上设置 exact(精准匹配) strict(严格匹配)/ Redirect:实现路由重定向
受路由管控组件的3个属性
基于<Route...>渲染的组件都是受路由管控的
受路由管控的组件,在属性中都有三个属性 this.props
HASH路由自己模拟了一套History Api的机制(历史记录池),每一次的路由切换和跳转都会向池子中追加一条记录
history:{
* length:记录历史记录池中的数量
* go(n):跳转到指定的记录 go(-1)=>goBack() /go(1)=>goForward()
* push:跳转到指定的路由地址,也是向池子中追加一条新的记录
this.pros.history.push(xxx)
}
location:{
pathname:跳转的路径地址;
search:问号传参的信息
hash:哈希值
state:传递进来的信息
}
match:{} 存储一些路由解析地址后的规则和结果
-
不受路由管控,默认属性中没有history/location等内容
* 想让其变成受路由管控的,或者想要这些属性,只需要基于react-router-dom中的withRouter高阶组件代理一下即可; * 用withRouter代理的组件必须在HashRouter或者BrowserRouter中
export default withRouter(nav);
LINK vs navLink
不管是Link 还是NavLink都是为了实现路由的跳转(最后渲染为A标签)
- Link 类似于普通A标签,通过Link中的to可以跳转到具体的路由页面
- NavLink:会根据浏览器地址中的地址和NavLink指定的to中的地址进行匹配,如果匹配上,则会给A设置一个class='active'
to = '/';
to = {{
pathname: '/',
search: '?xxx=xxx',
hash: '#xxx'
}}
看以下组件
import React, { Component } from 'react';
import { Switch, Route, Redirect, Link, NavLink } from 'react-router-dom';
import CustomList from './Custom/CustomList';
import CustomHandle from './Custom/CustomHandle';
class Custom extends Component {
render() {
return <>
<div className='menuBox'>
<link to='/custom/list'>我的客户</link>
<link to={{
pathname: '/custom/list',
search: '?lx=all'
}}>全部客户</link>
<link to='/custom/handle'>我的客户</link>
</div>
{/* 二级路由 */}
<Switch>
<Redirect from='custom' exact to='custom/list'/>
<Route path ='custom/list' Component={CumstomList}/>
<Route path ='custom/handle' exact Component={CumstomHandle}/>
<Route path ='custom/handle/:customId' Component={CumstomHandle}/>
<!--路径参数-->
</Switch>
</>;
}
}
子组件
class CustomList extends Component {
render() {
let search = this.props.location.search,
state = this.props.location.state;
return <>
客户列表 === {search ? '全部客户' : '我的客户'}
</>;
}
}
// ==========================
class CustomHandle extends Component {
render() {
return <>
客户{this.props.match.params.customId?'修改':'新增'}
</>
// 路径参数:custom/handle/:customId =>custom/handle/100
// =>this.props.match.params 在这里存储了路径参数
}
}
NavLink
class Nav extends Component {
render() {
return <header style={{background:'lightblue'}} className = 'navbox'>
<NavLink to='custom'>客户管理</NavLink>
<NavLink to='system'>系统设置</NavLink>
</header>
// 路径参数:custom/handle/:customId =>custom/handle/100
// =>this.props.match.params 在这里存储了路径参数
}
}
export default withRouter(Nav);
可以给active设置样式
.headerBox{
a{
color:#000;
}
&.actve{
color:red;
}
}
Nav本身不受路由管控,默认实行中没有history/location等内容;
想让其变成受路由管控的,或者想要这些属性,只需基于react-router-dom中的withRouter高阶组件代理一下即可;
用withRouter代理的组件必须在HashRouter或BrowerRouter中