路由有两种模式:一种是 hash
模式、另一种是 history
模式,在使用 vue-cli
以及 vue-router
默认搭建的 Vue
项目,若不做特殊的配置,默认就是 hash
模式。
1# 哈希模式
vue-router
默认为 hash
模式,使用 URL 的 hash
值来模拟一个完整的 URL,当 URL 改变时,页面不会重新加载。
hash 路由模式是这样的:http://www.example.com/#/xx
。 #
号后面就是 hash
值,改变后面的 hash
值,它不会向服务器发出请求,因此也就不会刷新页面。并且每次 hash
值发生改变的时候,会触发 hashchange
事件。
js
windows.addEventListener('hashchange', () => {
console.log(window.location.hash); // 打印 hash 值
})
2# 历史模式
在 vue-router
实例化配置对象中添加mode: history
便会由 hash
模式变为 histroy
模式。
js
const router = new VueRouter({
mode: 'history',
routes: [xxx]
})
history 路由模式是这样的:http://www.example.com/xxx
,不带 #
号。
2.1 pushState() 与 replaceState()
vue-router
会通过 history.pushState()
方法或 history.replaceState()
方法来改变 URL 的路径部分,而不刷新页面。
pushState()
方法用于在历史中添加一条记录,该方法不会触发页面刷新,只是导致 History 对象发生变化,地址栏会有变化。
语法:history.pushState(stateObject, title, url)
stateObject
:传递到新页面的数据对象。如果不需要传递数据,可以传入 null。title
:指定标题,但大多数浏览器并不使用这个参数,所以通常可以传入空字符串。url
:新的网址,必须与当前页面处在同一个域。如果不指定,则默认为当前路径。如果设置了一个跨域网址,则会报错。
注意: 如果
pushState
的 url 参数设置了一个新的锚点值(即 hash 值),并不会触发 hashchange 事件。 反过来,如果 URL 的锚点值变了,则会在 History 对象创建一条浏览记录。
replaceState()
方法用来修改 History 对象中的当前记录,用法与 pushState()
方法一样。
语法:history.replaceState(stateObject, title, url)
stateObject
:传递到新页面的数据对象。如果不需要传递数据,可以传入 null。title
:指定标题,但大多数浏览器并不使用这个参数,所以通常可以传入空字符串。url
:新的网址,必须与当前页面处在同一个域。如果不指定,则默认为当前路径。如果设置了一个跨域网址,则会报错。
js
history.pushState({data: 1}, '', '?page=1')
// URL 显示为 http://www.example.com/index.html?page=1
history.pushState({data: 2}, '', '?page=2');
// URL 显示为 http://www.example.com/index.html?page=2
history.replaceState({data: 3}, '', '?page=3');
// URL 显示为 http://www.example.com/index.html?page=3
history.pushState(null, '', 'https://www.xxx.com/index.html');
// 会报错
2.2 popstate 事件
每当 history 对象出现变化时,就会触发 popstate
事件,仅仅调用 pushState()
方法或 replaceState()
方法 ,并不会触发该事件。只有用户点击浏览器倒退按钮和前进按钮,或者调用History.back()
、History.forward()
、History.go()
方法时才会触发该事件。另外,该事件只针对同一个文档,如果浏览历史的切换,导致加载不同的文档,该事件也不会触发。
注意 :页面第一次加载的时候,浏览器不会触发 popstate 事件。
使用的时候,可以为 popstate
事件指定回调函数,它的参数是一个 event
事件对象,其 state
属性指向当前的 state
对象,相当于 history.state
对象。
js
window.addEventListener('popstate', function (e) {
console.log(e.state);// 相当于 history.state
console.log(history.state);
})