前端路由起源于 SPA 单页应用架构(现代前端开发中最流行的页面模型):

  • 单页面应用指的是应用实际只有一个主页面,页面间的切换实际是 DOM 结构的动态替换。(优点:无刷新,用户体验好)
  • 基于 React 的 SPA 应用,所有页面由不同的组件构成,页面的切换其实就是不同组件的切换。

原理:监测浏览器地址栏的变化,并进行路由匹配渲染对应的组件

React-Router路由组件

一般情况下

  • Demo 编写路由链接—点击跳转
  • 注册路由 明确路径和组件
  • 将路由链接&&注册路由 写到同一个

    1. import React from "react";
    2. //为什么不引入react-router?因为react-router提供了核心API,没有提供DOM相关进行路由跳转API
    3. //react-router-dom提供了BrowserRouter、Route、Link等api,可以操作DOM触发事件控制路由。
    4. import {BrowserRouter||HashRouter as Router,Route,Link} from "react-router-dom";
    5. //还有Redirect Switch
    6. //页面组件
    7. import Login from "./pages/Login"
    8. import Home from "./pages/Home"
    9. import Error404 from "./pages/Error404";
    10. export default function RouterExample() {
    11. return (
    12. <Router>
    13. <div>
    14. <ul>
    15. //路由链接实现切换组件--编写路由链接
    16. <li><Link to="/home">Home</Link></li>
    17. <li><Link to="/login">Login</Link></li>
    18. <li><Link to="/error/404">Error404</Link></li>
    19. </ul>
    20. <hr/>
    21. <div>
    22. //注册路由 exact严格模式 默认模糊匹配
    23. //开启严格模式之后,"输入的路径"必须包含要"匹配的路径",且顺序要一致
    24. <Route path="/home" exact={true} component={Home}></Route>
    25. <Route path="/login" component={Login}></Route>
    26. //嵌套路由 需要匹配完整路由
    27. <Route path="/error/404" component={Error404}></Route>
    28. //Switch模式注册路由 一一匹配
    29. <Switch>
    30. <Route path="/home" component={Home}></Route>
    31. <Route path="/login" component={Login}></Route>
    32. <Route path="/error/404" component={Error404}></Route>
    33. //都没有匹配中 跳转/home
    34. <Redirect to="/home"></Redirect>
    35. </Switch>
    36. </div>
    37. </div>
    38. </Router>
    39. );
    40. }

    React-Router路由参数

    React组件分为两种,路由组件非路由组件。默认情况下,只有路由组件能获取到路由参数
    路由组件:经由标签注册配置的自定义组件

    1. //JSX
    2. #1 params参数
    3. <Link to='/demo/test/tom/18'}>详情</Link>
    4. 注册路由(声明接收):<Route path="/demo/test/:name/:age" component={Test}/>
    5. 接收参数:this.props.match.params
    6. #2 search参数
    7. 路由链接(携带参数):<Link to='/demo/test?name=tom&age=18'}>详情</Link>
    8. 注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
    9. 接收参数:this.props.location.search
    10. 备注:获取到的searchurlencoded编码字符串,需要借助querystring解析
    11. #3 state参数
    12. 路由链接(携带参数):
    13. <Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>
    14. 注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
    15. 接收参数: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() }

  1. render() {
  2. console.log('当前组件收到的props是',this.props);
  3. return (
  4. <div>
  5. <button onClick={this.goBack}>回退</button>&nbsp;
  6. </div>
  7. )
  8. }

} export default withRouter(Header) //withRouter可以加工一般组件,让一般组件具备路由组件所特有的API //withRouter的返回值是一个新组件

  1. <a name="uv0Wb"></a>
  2. #### 编程式路由导航
  3. **路由组件**中,可以使用编程的方式进行路由跳转
  4. ```jsx
  5. //路由组件:可以在props属性中获取history对象
  6. //非路由组件,可以通过withRouter函数的包装获取到this.props.history对象
  7. //借助this.props.history对象的方法来操作路由跳转、前进、后退
  8. this.props.history.push()
  9. this.props.history.replace()
  10. this.props.history.goBack()
  11. this.props.history.goForward()
  12. 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参数的丢失!!!

参考

  1. https://cloud.tencent.com/developer/article/1625690 前端路由
  2. https://zhuanlan.zhihu.com/p/360582577 React路由原理
  3. https://www.ngui.cc/article/show-312531.html React路由笔记
  4. http://react-guide.github.io/react-router-cn/ React-Router文档