为了构建SPA(单页面应用),需要引入前端路由系统,这也就是VUE-Router存在的意义。前端路由的核心就在于改变视图的同时不会向后端发出请求,为了达到这种目的,浏览器当前提供了一下两种支持:hash和history。

  1. /* hash */
  2. https://www.abc.com/#/home
  3. /* history */
  4. https://www.abc.com/home

hash模式

hash即URL中的#符号,而不是指哈希运算,例如 https://www.abc.com/#/home ,hash的值为 #/home它的特点在于hash虽然会出现在URL中,但不会被包括在HTTP请求中,对后端完全没有影响,因此改变hash不会重新加载页面。
**
hash模式的背后是 onhashchange 事件,可以在 window 对象上监听这个事件。

window.onhashchange = function(event){
  const hash = location.hash.slice(1);
  console.log(event.oldURL,event.newURL,hash);
}

hash发生变化的url都会被浏览器记录下来,从而你会发现浏览器的前进后退都可以使用了,同时点击后退时,页面字体颜色也会发生变化。这样一来虽然没有向后端发送请求,但是页面状态和url关联在了一起,这就是前端路由。

history模式

history模式是利用了HTML5 History Interface中新增的pushState()和replaceState()方法。这两个方法应用于浏览器的历史记录栈,在当前已有的back、forward、go的基础上,它们提供了对历史记录进行修改的功能。只要当它们执行修改时,虽然改变了当前的URL,但浏览器不会立即向后端发送请求。

history模式包括了 go()forward()back() 方法。

// 直接跳往指定页面
history.go(-2);  // 往前跳两页
history.go(2);   // 往后跳两页

history.forward();  // 下一页
history.back();    // 上一页

history模式下还可以修改历史状态,包括了 pushState()replaceState() 方法,它们有三个参数: stateObjtitleurl

// 设置状态
history.pushState(stateObj,title,url);

// 监听状态
window.onpopstate = function(event){
  console.log(event.state);
}

通过 pushState 把页面的状态保存在 state 对象中,当页面的 url 再变回到这个 url 时,可以通过 event.state 取到这个 state 对象,从而可以对页面状态进行还原,如页面滚动条的位置、阅读进度、组件的开关等。

hash和history模式比较

hash模式的优势:

  • hash模式下,仅hash符号之前的内容会被包含在请求中,例如 https://www.abc.com ,因此对于后端来说,即使没有做到对路由的全覆盖也不会返回404错误
  • history模式下,前端的url必须和后端发起请求的url一致,例如https://www.abc.com/home如果后端缺少了 /home 的路由处理,就会返回404。

    history模式的优势

  • history模式的pushState 设置的 url 可以是同源下的任意 url;而 hash 只能修改 # 后面的部分,因此只能设置当前 url 同文档的 url。

  • history模式的pushState 设置的新的 url 可以与当前 url 一样,这样也会把记录添加到栈中;hash 设置的新值不能与原来的一样,一样的值不会触发动作将记录添加到栈中。
  • history模式的pushState 通过 stateObj 参数可以将任何数据类型添加到记录中;hash 只能添加短字符串。
  • history模式的pushState 可以设置额外的 title 属性供后续使用。