为了构建SPA(单页面应用),需要引入前端路由系统,这也就是VUE-Router存在的意义。前端路由的核心就在于改变视图的同时不会向后端发出请求,为了达到这种目的,浏览器当前提供了一下两种支持:hash和history。
/* hash */
https://www.abc.com/#/home
/* history */
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()
方法,它们有三个参数: stateObj
、 title
和 url
。
// 设置状态
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 属性供后续使用。