Vue-router中hash模式与history模式的区别详解


Posted in Vue.js onDecember 15, 2020

VUE路由的hash模式与history模式的区别,这个也是面试常问的问题,这个题其实就是考验你的开发经验是否属实。

小白回答:hash模式url带#号,history模式不带#号。

大牛解答:

形式上:hash模式url里面永远带着#号,开发当中默认使用这个模式。如果用户考虑url的规范那么就需要使用history模式,因为history模式没有#号,是个正常的url,适合推广宣传;

功能上:比如我们在开发app的时候有分享页面,那么这个分享出去的页面就是用vue或是react做的,咱们把这个页面分享到第三方的app里,有的app里面url是不允许带有#号的,所以要将#号去除那么就要使用history模式,但是使用history模式还有一个问题就是,在访问二级页面的时候,做刷新操作,会出现404错误,那么就需要和后端人配合,让他配置一下apache或是nginx的url重定向,重定向到你的首页路由上就ok了

正题开始

为了达到改变视图的同时不会向后端发出请求这一目的,浏览器当前提供了以下两种支持:

hash模式:即地址栏 URL 中的 # 符号

比如这个 URL:http://www.abc.com/#/hello, hash 的值为 #/hello

它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。

history模式:利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)

这两个方法应用于浏览器的历史记录栈,在当前已有的 back()、forward()、go() 方法的基础之上,这两个方法提供了对历史记录进行修改的功能。当这两个方法执行修改时,只能改变当前地址栏的 URL,但浏览器不会向后端发送请求,也不会触发popstate事件的执行

因此可以说,hash 模式和 history 模式都属于浏览器自身的特性,Vue-Router 只是利用了这两个特性(通过调用浏览器提供的接口)来实现前端路由.

vue中的router有两种模式:hash模式(默认)、history模式(需配置mode: 'history')

Vue-router中hash模式与history模式的区别详解

vue中的hash模式

即地址栏 URL 中的 # 符号,这个#就是hash符号,中文名哈希符或锚点

比如这个 URL:http://www.baidu.com/#/home,hash 的值为 #/home

它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。

Vue-router中hash模式与history模式的区别详解

路由的哈希模式其实是利用了window.onhashchange事件,也就是说你的url中的哈希值(#后面的值)如果有变化,就会自动调用hashchange的监听事件,在hashchange的监听事件内可以得到改变后的url,这样能够找到对应页面进行加载

window.addEventListener('hashchange', () => {
  // 把改变后的url地址栏的url赋值给data的响应式数据current,调用router-view去加载对应的页面
  this.data.current = window.location.hash.substr(1)
})

vue中history模式

HTML5 History Interface 中新增的两个神器 pushState() 和 replaceState() 方法(需要特定浏览器支持),用来完成 URL 跳转而无须重新加载页面,不过这种模式还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,就需要前端自己配置404页面。

Vue-router中hash模式与history模式的区别详解

pushState() 和 replaceState() 这两个神器的作用就是可以将url替换并且不刷新页面,好比挂羊头卖狗肉,http并没有去请求服务器该路径下的资源,一旦刷新就会暴露这个实际不存在的“羊头”,显示404(因为浏览器一旦刷新,就是去真正请求服务器资源)

那么如何去解决history模式下刷新报404的弊端呢,这就需要服务器端做点手脚,将不存在的路径请求重定向到入口文件(index.html),前后端联手,齐心协力做好“挂羊头卖狗肉”的完美特效

pushState方法、replaceState方法,只能导致history对象发生变化,从而改变当前地址栏的 URL,但浏览器不会向后端发送请求,也不会触发popstate事件的执行

popstate事件的执行是在点击浏览器的前进后退按钮的时候,才会被触发

window.addEventListener('popstate', () => {
 this.data.current = window.location.pathname
})

使用场景

一般场景下,hash 和 history 都可以,除非你更在意颜值,# 符号夹杂在 URL 里看起来确实有些不太美丽。

如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成URL 跳转而无须重新加载页面。 Vue-router 另外,根据 Mozilla Develop Network 的介绍,调用 history.pushState() 相比于直接修改 hash,存在以下优势:

pushState() 设置的新 URL 可以是与当前 URL 同源的任意 URL;而 hash 只可修改 # 后面的部分,因此只能设置与当前 URL 同文档的 URL

pushState() 设置的新 URL 可以与当前 URL 一模一样,这样也会把记录添加到栈中;而 hash 设置的新值必须与原来不一样才会触发动作将记录添加到栈中

pushState() 通过 stateObject 参数可以添加任意类型的数据到记录中;而 hash 只可添加短字符串

pushState() 可额外设置 title 属性供后续使用

总结

传统的路由指的是:当用户访问一个url时,对应的服务器会接收这个请求,然后解析url中的路径,从而执行对应的处理逻辑。这样就完成了一次路由分发

而前端路由是不涉及服务器的,是前端利用hash或者HTML5的history API来实现的,一般用于不同内容的展示和切换

到此这篇关于Vue-router中hash模式与history模式的区别详解的文章就介绍到这了,更多相关Vue-router中hash模式与history模式区别内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Vue.js 相关文章推荐
vue使用vant中的checkbox实现全选功能
Nov 17 Vue.js
Vue与React的区别和优势对比
Dec 18 Vue.js
vue 使用class创建和清除水印的示例代码
Dec 25 Vue.js
Vue实现随机验证码功能
Dec 29 Vue.js
Vue包大小优化的实现(从1.72M到94K)
Feb 18 Vue.js
原生JS封装vue Tab切换效果
Apr 28 Vue.js
Vue接口封装的完整步骤记录
May 14 Vue.js
Vue3如何理解ref toRef和toRefs的区别
Feb 18 Vue.js
vue-cli3.0修改打包后的文件名和文件地址,打包后本地运行报错解决
Apr 06 Vue.js
如何优化vue打包文件过大
Apr 13 Vue.js
vue项目打包后路由错误的解决方法
Apr 13 Vue.js
vue @ ~ 相对路径 路径别名设置方式
Jun 05 Vue.js
vue项目中企业微信使用js-sdk时config和agentConfig配置方式详解
Dec 15 #Vue.js
Vue解决移动端弹窗滚动穿透问题
Dec 15 #Vue.js
8个非常实用的Vue自定义指令
Dec 15 #Vue.js
vue从后台渲染文章列表以及根据id跳转文章详情详解
Dec 14 #Vue.js
Vue在H5 项目中使用融云进行实时个人单聊通讯
Dec 14 #Vue.js
vue的hash值原理也是table切换实例代码
Dec 14 #Vue.js
Vue如何跨组件传递Slot的实现
Dec 14 #Vue.js
You might like
建立文件交换功能的脚本(一)
2006/10/09 PHP
PHP header函数分析详解
2011/08/06 PHP
php笔记之:php函数range() round()和list()的使用说明
2013/04/26 PHP
探讨各种PHP字符串函数的总结分析
2013/06/05 PHP
PHP的Json中文处理解决方案
2016/09/29 PHP
PHP设计模式之适配器模式原理与用法分析
2018/04/25 PHP
PHP操作redis实现的分页列表,新增,删除功能封装类与用法示例
2018/08/04 PHP
关于laravel 子查询 & join的使用
2019/10/16 PHP
PHP使用递归按层级查找数据的方法
2019/11/10 PHP
PHP实现简单注册登录系统
2020/12/28 PHP
javascript Keycode对照表
2009/10/24 Javascript
IE 当eval遇上function的处理
2011/08/09 Javascript
javascript中call和apply方法浅谈
2013/09/27 Javascript
jquery.fastLiveFilter.js实现输入自动过滤的方法
2015/08/11 Javascript
使用jQuery mobile库检测url绝对地址和相对地址的方法
2015/12/04 Javascript
JavaScript中Window对象的属性及事件
2015/12/25 Javascript
javascript实现仿百度图片的瀑布流加载效果
2016/04/20 Javascript
Vue+jquery实现表格指定列的文字收缩的示例代码
2018/01/09 jQuery
Vue实现本地购物车功能
2018/12/05 Javascript
详解滑动穿透(锁body)终极探索
2019/04/16 Javascript
Vue实现购物车的全选、单选、显示商品价格代码实例
2019/05/06 Javascript
[06:40]2014DOTA2西雅图国际邀请赛 DK战队巡礼
2014/07/07 DOTA
Pycharm导入Python包,模块的图文教程
2018/06/13 Python
解决Python3 控制台输出InsecureRequestWarning问题
2019/07/15 Python
用Python实现二叉树、二叉树非递归遍历及绘制的例子
2019/08/09 Python
Python中文分词库jieba,pkusegwg性能准确度比较
2020/02/11 Python
python对数组进行排序,并输出排序后对应的索引值方式
2020/02/28 Python
Python ArgumentParse的subparser用法说明
2020/04/20 Python
英国家喻户晓的高街品牌:River Island
2017/11/28 全球购物
小学教师的自我评价范例
2013/10/31 职场文书
英语专业毕业生自我鉴定
2013/11/09 职场文书
小学生家长评语大全
2014/02/10 职场文书
学校端午节活动方案
2014/08/23 职场文书
奉献家乡演讲稿
2014/09/16 职场文书
机关干部四风问题自查报告及整改措施
2014/10/26 职场文书
医学会议开幕词
2016/03/03 职场文书