Vue-Router:Hash&History两种路由模式对比

本文最后更新于:8 个月前

Vue Router有两种路由模式:Hash和History,它们的实现原理各是怎样的呢?

Hash & History两种路由模式对比

一、Hash模式

核心:监听hashchange事件
  • 定义

    hash 模式是一种把前端路由的路径用井号 # 拼接在真实 URL 后面的模式。当井号 # 后面的路径发生变化时,页面发生变化。

  • 优点

    兼容性好

  • 模拟示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <body>
    <main>
    <a href="#/a">A页面</a>
    <a href="#/b">B页面</a>
    <p>hash模式,当#后面的锚点发生变化时,会触发hashchange事件,可以通过监听该事件来实现路由跳转逻辑(点击链接,注意观察下面路径的变化)</p>
    <div id="app"></div>
    </main>

    <script>
    const app = document.getElementById('app')
    function render() {
    app.innerText = window.location.href
    }

    window.addEventListener('hashchange', render)

    render()
    </script>
    </body>

二、History模式

核心:HTML5的History对象,监听popstate事件
  • 定义

    当path发生变化后,页面发生变化,但是不会重新发送请求。

    利用的是HTML5 提供的 History API,开发者对路由进行修改,即更新浏览器 URL 地址,不会重新发起请求。

    window.history对象保存了浏览器当前窗口的浏览历史

    History对象有一个popstate事件,每当History对象发生改变时,就会触发这个事件(pushSate、replaceState方法除外)

  • 模拟实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    <body>
    <main>
    <h2>history模式</h2>
    <a href="javascript:toA()">A页面</a>
    <a href="javascript:toB()">B页面</a>
    <div id="app"></div>
    </main>

    <script>
    const app = document.getElementById('app')
    function render() {
    app.innerText = window.location.pathname
    }

    // pushState方法不会触发popstate事件,所以需要单独调用render
    function toA() {
    history.pushState({}, null, '/a')
    render()
    }

    function toB() {
    history.pushState({}, null, '/b')
    render()
    }

    window.addEventListener('popstate', render)

    render()
    </script>
    </body>

    需要借助web 框架来打开该页面,不能从本地直接打开,因为那样的话,跳转到路径会变成本地/a,无法正确访问到资源

    1
    2
    npm install -g light-server
    light-server -s . --historyindex '/history.html' --port 3000

    . --historyindex表示如果后端资源不存在就返回 history.html 的内容。

    浏览器刷新时,会按照路径发送真实的路径请求,如果这个路径恰好是 history API设置的话,服务端往往都是没有这个资源的,于是就返回404了。

    所以线上部署 History路由模式 的 单页面应用时,需要后端配合,否则会请求不到资源而报错。以Nginx为例,需要在配置的 网页路径location下增加一行

    1
    try_files $uri /index.html;
  • 优点

    路径看起来比较美观

  • 缺点

    (1)兼容性不如Hash模式好

    (2)需要服务端支持,否则可能会404

  • 验证:History API 不会重新发送请求

    (1)下图是第一次请求页面的网络请求

    image-20230515213040351

    (2)下图是点击了多次 A页面B页面链接后的请求

    image-20230515213159545

    可以看到,调用 History API 改变页面 url 之后,并没有对页面重新请求,而是只对favicon.ico文件进行了请求!


Vue-Router:Hash&History两种路由模式对比
http://timegogo.top/2023/05/15/Vue/Vue-Router:两种路由方式对比/
作者
丘智聪
发布于
2023年5月15日
更新于
2023年7月16日
许可协议