前端路由起源于 SPA 单页应用架构(现代前端开发中最流行的页面模型):
- 单页面应用指的是应用实际只有一个主页面,页面间的切换实际是 DOM 结构的动态替换。(优点:无刷新,用户体验好)
- 基于 React 的 SPA 应用,所有页面由不同的组件构成,页面的切换其实就是不同组件的切换。
React-Router路由组件
一般情况下
- Demo 编写路由链接—点击跳转
注册路由 明确路径和组件 将路由链接&&注册路由 写到同一个
或 中 import React from "react";
//为什么不引入react-router?因为react-router提供了核心API,没有提供DOM相关进行路由跳转API
//react-router-dom提供了BrowserRouter、Route、Link等api,可以操作DOM触发事件控制路由。
import {BrowserRouter||HashRouter as Router,Route,Link} from "react-router-dom";
//还有Redirect Switch
//页面组件
import Login from "./pages/Login"
import Home from "./pages/Home"
import Error404 from "./pages/Error404";
export default function RouterExample() {
return (
<Router>
<div>
<ul>
//路由链接实现切换组件--编写路由链接
<li><Link to="/home">Home</Link></li>
<li><Link to="/login">Login</Link></li>
<li><Link to="/error/404">Error404</Link></li>
</ul>
<hr/>
<div>
//注册路由 exact严格模式 默认模糊匹配
//开启严格模式之后,"输入的路径"必须包含要"匹配的路径",且顺序要一致
<Route path="/home" exact={true} component={Home}></Route>
<Route path="/login" component={Login}></Route>
//嵌套路由 需要匹配完整路由
<Route path="/error/404" component={Error404}></Route>
//Switch模式注册路由 一一匹配
<Switch>
<Route path="/home" component={Home}></Route>
<Route path="/login" component={Login}></Route>
<Route path="/error/404" component={Error404}></Route>
//都没有匹配中 跳转/home
<Redirect to="/home"></Redirect>
</Switch>
</div>
</div>
</Router>
);
}
React-Router路由参数
React组件分为两种,路由组件、非路由组件。默认情况下,只有路由组件能获取到路由参数
路由组件:经由标签注册配置的自定义组件 //JSX
#1 params参数
<Link to='/demo/test/tom/18'}>详情</Link>
注册路由(声明接收):<Route path="/demo/test/:name/:age" component={Test}/>
接收参数:this.props.match.params
#2 search参数
路由链接(携带参数):<Link to='/demo/test?name=tom&age=18'}>详情</Link>
注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
接收参数:this.props.location.search
备注:获取到的search是urlencoded编码字符串,需要借助querystring解析
#3 state参数
路由链接(携带参数):
<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>
注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
接收参数:this.props.location.state
withRouter—非路由组件获取this.props.history
非路由组件的props属性无法接收到history对象属性,使用withRouter高阶组件即可使得非路由组件的props属性注入history对象属性 ```jsx import React, { Component } from ‘react’ import {withRouter} from ‘react-router-dom’
class Header extends Component { goBack = ()=>{ this.props.history.goBack() }
render() {
console.log('当前组件收到的props是',this.props);
return (
<div>
<button onClick={this.goBack}>回退</button>
</div>
)
}
} export default withRouter(Header) //withRouter可以加工一般组件,让一般组件具备路由组件所特有的API //withRouter的返回值是一个新组件
<a name="uv0Wb"></a>
#### 编程式路由导航
**路由组件**中,可以使用编程的方式进行路由跳转
```jsx
//路由组件:可以在props属性中获取history对象
//非路由组件,可以通过withRouter函数的包装获取到this.props.history对象
//借助this.props.history对象的方法来操作路由跳转、前进、后退
this.props.history.push()
this.props.history.replace()
this.props.history.goBack()
this.props.history.goForward()
this.props.history.go()
BrowserRouter与HashRouter的区别
- BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。HashRouter使用的是URL的哈希值。二者实现原理不同
- Path路径不一致。HashRouter的路径包含#而BrowserRouter不包含。比如http://localhost:8080/#/test/
- State参数下 刷新是否清空参数
- BrowserRouter没有任何影响,因为state保存在history对象中
- HashRouter刷新后会导致路由state参数的丢失!!!