完全搞懂路由跳转:location 和 history 接口

在单页应用中,一般由前端来配置路由,根据不一样的 url 显示不一样的内容。想要知道这是如何作到的,首先得了解浏览器提供的两大 API:前端

  1. window.locationvue

    • location.href
    • location.hash
    • location.search
    • location.pathname
  2. window.historyvue-router

    • history.pushState()
    • history.replaceState()
    • history.go()
    • history.back()
    • history.forward()

window.location

咱们先了解 location 对象,location 有不少的属性。咱们能够经过改变其属性值修改页面的 url。咱们在单页应用中须要作到的是改变 url 不刷新页面,location 接口提供如下两种方式能够作到:后端

  1. location.href 赋值时只改变 url 的 hash
    图片描述
  2. 直接赋值 location.hash
    图片描述

而上面的列出其他两个属性 location.search 会直接刷新页面,这个就不解释了。但 location.pathname 照道理来讲只改变 hash 应该是能够的,但实际上浏览器会编码这个属性值,因此没法直接赋带 # 号的值。浏览器

window.history

history 接口是 HTML5 新增的,它有五个方法能够改变 url 而不刷新页面。编码

  1. history.pushState()
    图片描述
  2. history.replaceState()
    图片描述
  3. history.go()
    图片描述

上面只演示了三个方法,由于 history.back() 等价于 history.go(-1)history.forward() 则等价于 history.go(1),这三个接口等同于浏览器界面的前进后退。url

如何监听 url 的变化

如今咱们已经知道如何不刷新页面改变页面的 url。虽然页面没刷新,但咱们要改变页面显示的内容。这就须要 js 监听 url 的变化从而达到咱们的目的。spa

咱们有两个事件能够监听 url 的改变:code

hashchange

hashchange 事件能监听 url hash 的改变。router

先要加上事件监听的代码:

window.addEventListener('hashchange', function(e) {
  console.log(e)
})

而后就能够在页面的 console 里愉快的实验了:

图片描述

从上图中咱们能够知道无论是经过 location 接口直接改变 hash,仍是经过 history 接口前进后退(只是 hash 改变的状况下),咱们均可以监听到 url hash 的改变。但这个事件也只能监听 url hash 的变化。因此咱们须要一个更强大的事件:popstate

popstate

popstate 事件能监听除 history.pushState()history.replaceState() 外 url 的变化。

先加上事件监听的代码:

window.addEventListener('popstate', function(e) {
  console.log(e)
})

而后又能够在页面的 console 里愉快的实验了:

图片描述

其实不止 history.pushState()history.replaceState() 对 url 的改变不会触发 popstate 事件,当这两个方法只改变 url hash 时也不会触发 hashchange 事件。

hash 模式和 history 模式

咱们都知道单页应用的路由有两种模式:hash 和 history。若是咱们在 hash 模式时不使用 history.pushState()history.replaceState() 方法,咱们就只须要在 hashchange 事件回调里编写 url 改变时的逻辑就好了。而 history 模式下,咱们不只要在 popstate 事件回调里处理 url 的变化,还须要分别在 history.pushState()history.replaceState() 方法里处理 url 的变化。并且 history 模式还须要后端的配合,否则用户刷新页面就只有 404 能够看了?

因此 hash 模式下咱们的工做实际上是更简单的,但为何如今都推荐用 history 模式呢?总不是 hash 模式下的 url 太丑了,毕竟这是个看脸的世界?

不过 vue-router 在浏览器支持 pushState() 时就算是 hash 模式下也是用 history.pushState() 来改变 url,不知道有没什么深意?还有待研究...

相关文章
相关标签/搜索