这个问题的要点在于vue-router两种模式下如何实现的url到组件的映射。好了,废话不多少,看一下vue单页面应用无刷新更新组件的两种主要实现方式。
一.hash模式
hash模式是vue-router的默认模式。hash指的是url描点,当描点发生变化的时候,浏览器只会修改访问历史记录,不会访问服务器重新获取页面。因此可以监听描点值的变化,根据描点值渲染指定dom。
改变描点
可以通过location.hash = "/hashpath"的方式修改浏览器的hash值。
监听描点变化
可以通过监听hashchange事件监听hash值的变化。
window.addEventListener('hashchange', () => {
const hash = window.location.hash.substr(1)
// 根据hash值渲染不同的dom
})
二.history模式
通过mode选项开启history模式,history 模式和 hash 模式的区别在于:
1.history模式中不带有“#”,更加美观
2.history模式当用户刷新或直接输入地址时会向服务器发送一个请求,所以history模式需要服务端同学进行支持,将路由都重定向到根路由
改变url
H5的history对象提供了pushState和replaceState两个方法,当调用这两个方法的时候,url会发生变化,浏览器访问历史也会发生变化,但是浏览器不会向后台发送请求。
// 第一个参数:data对象,在监听变化的事件中能够获取到
// 第二个参数:title标题
// 第三个参数:跳转地址
history.pushState({}, "", '/a')
监听url变化
可以通过监听popstate事件监听history变化,也就是点击浏览器的前进或者后退功能时触发。
window.addEventListener("popstate", () => {
const path = window.location.pathname
// 堆代码 duidaima.com
// 根据path不同可渲染不同的dom
})
从某种程度来说,调用 pushState() 和 window.location = "#foo"基本上一样,他们都会在当前的 document 中创建和激活一个新的历史记录。但是 pushState() 有以下优势:
1.新的 URL 可以是任何和当前 URL 同源的 URL。但是设置 `window.location`[6] 只会在你只设置锚的时候才会使当前的 URL。
2.非强制修改 URL。相反,设置 window.location = "#foo"; 仅仅会在锚的值不是 #foo 情况下创建一条新的历史记录。
3.可以在新的历史记录中关联任何数据。window.location = "#foo"形式的操作,你只可以将所需数据写入锚的字符串中。
注意: pushState() 不会造成 `hashchange`[7] 事件调用,即使新的 URL 和之前的 URL 只是锚的数据不同。----MDN