参考文章:
https://zhuanlan.zhihu.com/p/27588422
https://juejin.im/post/5b5697675188251b11097464
https://ustbhuangyi.github.io/vue-analysis/v2/vue-router/
基于vue,react等前端框架的SPA单页面应用的特点:“更新视图但不重新请求页面”。通过vue-router的源码,来具体了解下。
实现原理:
history模式:从HTML5开始,History interface提供了两个新的方法:
pushState()
,replaceState()
使得我们可以对浏览器历史记录栈进行修改
这两个方法有个共同的特点:当调用他们修改浏览器历史记录栈后,虽然当前URL改变了,但浏览器不会发送请求该URL。这样就可以来实现前端路由“更新视图但不重新请求页面”的功能了
window.history.pushState(stateObject, title, URL)
window.history.replaceState(stateObject, title, URL)
再搭配<router-link>
对a标签默认行为拦截,实现前端路由的跳转
下面是vue router
文档中的说明:
<router-link>
组件支持用户在具有路由功能的应用中 (点击) 导航。 通过 to
属性指定目标地址,默认渲染成带有正确链接的 <a>
标签,可以通过配置 tag
属性生成别的标签.。另外,当目标路由成功激活时,链接元素自动设置一个表示激活的 CSS 类名。
<router-link>
比起写死的 <a href="...">
会好一些,理由如下:
- 无论是 HTML5 history 模式还是 hash 模式,它的表现行为一致,所以,当你要切换路由模式,或者在 IE9 降级使用 hash 模式,无须作任何变动。
- 在 HTML5 history 模式下,
router-link
会守卫点击事件,让浏览器不再重新加载页面。 - 当你在 HTML5 history 模式下使用
base
选项之后,所有的to
属性都不需要写 (基路径) 了。
hash模式:“#”符号的本来作用是加在URL中指示网页中的位置(锚点)
#符号本身以及它后面的字符称之为hash,可通过window.location.hash
属性读取。它具有如下特点:
hash虽然出现在URL中,但不会被包括在HTTP请求中。它是用来指导浏览器动作的,对服务器端完全无用,因此,改变hash不会重新加载页面
可以为hash的改变添加监听事件:
window.addEventListener("hashchange", funcRef, false)每一次改变hash(window.location.hash),都会在浏览器的访问历史中增加一个记录
利用hash的以上特点,就可以来实现前端路由“更新视图但不重新请求页面”的功能了。