路由

4/8/2022 React

# 什么是路由

一个路由就是一个映射关系(key: value),其中 key 为路径,value 可能是 function 或 component

路由(Route)与路由器(Router)的区别:一个路由器管理着多个路由,每一个路由对应一台计算机,你可以把路由想象成是路由器上的一个插口,而路由器上有多个插口,每个插口连接着一台计算机

在 React 应用中,一个 React 应用(单页应用)使用一个路由器即可,所以你可以将整个应用用一个路由器组件包裹,在路由器组件内部的所有路由都归该路由器管理

# 路由的分类

  1. 后端路由

    1. 理解:value 是 function,用来处理客户端提交的请求
    2. 注册路由:router.get(path, function(req, res))
    3. 工作过程:当 node 接收到一个请求时,根据请求路径找到匹配的路由,调用路由中的函数来处理请求,返回响应数据
  2. 前端路由

    1. 理解:浏览器端路由,value 是 component,用于展示页面内容
    2. 注册路由:<Route path="/test" component={Test} />
    3. 工作过程:当浏览器的 path 变为 /test 时,当前路由组件就会启用 Test 组件

# history 对象

前端路由基石:history 对象

  1. 分类

    1. browser history: H5 提出的 history 对象,但兼容性相较于 hash history 不是很好
    2. hash history: 兼容性极佳,在 url 中 hash(#) 后面的内容不会发送给服务器,这在解决样式丢失问题会起作用
  2. React 中 BrowserRouter 和 HashRouter 的区别

    1. 底层原理不一样

      BrowserRouter 使用的是 H5 的 history API,不兼容 IE9 及以下版本

      HashRouter 使用的是 URL 的哈希值

    2. path 表现形式不一样

      BrowserRouter 的路径中没有 # ,例如:localhost:3000/demo/test

      HashRouter 的路径中包含 # ,例如:localhost:3000/#/demo/test

    3. 刷新后对路由 state 参数的影响

      BrowserRouter 没有任何影响,因为 state 保存在 history 对象中

      HashRouter 刷新后会导致 state 参数丢失

    注意⚠️:HashRouter 可以解决一些路径错误相关的问题,主要原因是因为 # 后面的内容不会发送给服务器

# 动态路由

在 v4 版本之前,React Router 一直使用的是静态路由,直到升级至 v4 版本后改为动态路由。所谓的动态路由就是在应用程序渲染时发生的路由,而不是在运行应用程序之外的配置或约定中发生的路由

# 解决样式丢失问题

<!-- index.html -->
<link rel="stylesheet" href="./css/index.css">

我们在 index.html 文件中通过 link 标签引入 css 样式文件。

注意⚠️:以上是通过相对路径进行引入的,这在实际开发过程中可能就会造成样式丢失问题,请看下面例子

// Demo 组件
export default class Demo extends Component {
  render() {
    return (
      <div>
        <ul>
          <li>
            <NavLink to="/lkj/about">About</NavLink>
          </li>
          <li>
            <NavLink to="/lkj/home">Home</NavLink>
          </li>
        </ul>
        <Route path="/lkj/about" component={About} />
        <Route path="/lkj/home" component={Home} />
      </div>
    )
  }
}

注意上面的路由,其路径为 /lkj/about/lkj/home,项目启动首次渲染时肯定是没问题滴,点击导航跳转路径显示对应的组件时也没问题,因为是单页应用,切换路由并不会重新向服务器发送请求。现在问题来了,当我们在此基础上刷新页面时为何页面中的样式会丢失呢?

「分析」

当你刷新页面时会重新向服务器发送请求,请求路径是 http://localhost:3000/lkj/about。由于是单页应用,服务器只发送给你 index.html 文件,而在该文件中又有请求样式文件的 link 标签,于是又会发送请求,由于 link 标签 <link rel="stylesheet" href="./css/index.css"> 是通过相对路径的方式引入样式文件的,而请求的路径又是 http://localhost:3000/lkj/about,所以最终请求的样式文件路径会变成为 http://localhost:3000/lkj/css/index.css,但是服务器上根本就找不到这种路径所对应的样式文件,自然页面上就不会有样式了。

「解决」

  1. 在 link 标签中的相对路径改成绝对路径 <link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="%PUBLIC_URL%/css/index.css"> 「推荐」
  2. 采用 HashRouter 的方式,因为 hash(#) 后面的内容即使你刷新页面也不会作为请求资源发送给服务器
Last Updated: 4/8/2022, 7:03:16 PM