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图片裁剪插件vue-cropper使用方法详解
Dec 16 Vue.js
vue 使用class创建和清除水印的示例代码
Dec 25 Vue.js
vue-quill-editor插入图片路径太长问题解决方法
Jan 08 Vue.js
vue 页面跳转的实现方式
Jan 12 Vue.js
vue 计算属性和侦听器的使用小结
Jan 25 Vue.js
深入了解Vue动态组件和异步组件
Jan 26 Vue.js
vue穿梭框实现上下移动
Jan 29 Vue.js
vue监听键盘事件的相关总结
Jan 29 Vue.js
Vue基本指令实例图文讲解
Feb 25 Vue.js
使用vue-element-admin框架从后端动态获取菜单功能的实现
Apr 29 Vue.js
Vue全局事件总线你了解吗
Feb 24 Vue.js
vue项目如何打包之项目打包优化(让打包的js文件变小)
Apr 30 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
PHP.ini中配置屏蔽错误信息显示和保存错误日志的例子
2014/05/12 PHP
destoon整合ucenter后注册页面不跳转的解决方法
2014/06/21 PHP
WordPress中给文章添加自定义字段及后台编辑功能区域
2015/12/19 PHP
PHP-FPM 的管理和配置详解
2019/02/17 PHP
laravel 解决强制跳转 https的问题
2019/10/22 PHP
用js实现下载远程文件并保存在本地的脚本
2008/05/06 Javascript
jQuery获取文本节点之 text()/val()/html() 方法区别
2011/03/01 Javascript
JavaScript 判断浏览器是否支持SVG的代码
2013/03/21 Javascript
使用JavaScript实现Java的List功能(实例讲解)
2013/11/07 Javascript
Jquery下EasyUI组件中的DataGrid结果集清空方法
2014/01/06 Javascript
jsp网页搜索结果中实现选中一行使其高亮
2014/02/17 Javascript
JS多文件上传的实例代码
2017/01/11 Javascript
js阻止移动端页面滚动的两种方法
2017/01/25 Javascript
JavaScript获取ul中li个数的方法
2017/02/13 Javascript
vuejs响应用户事件(如点击事件)
2017/03/14 Javascript
使用Node.js实现简易MVC框架的方法
2017/08/07 Javascript
详解angular分页插件tm.pagination二次触发问题解决方案
2018/07/20 Javascript
浅谈VUE-CLI脚手架热更新太慢的原因和解决方法
2018/09/28 Javascript
jQuery实现动态生成年月日级联下拉列表示例
2019/05/11 jQuery
Vue 请求传公共参数的操作
2020/07/31 Javascript
JavaScript 中的六种循环方法
2021/01/06 Javascript
Python中使用第三方库xlrd来写入Excel文件示例
2015/04/05 Python
python下paramiko模块实现ssh连接登录Linux服务器
2015/06/03 Python
Python浅复制中对象生存周期实例分析
2018/04/02 Python
pandas求两个表格不相交的集合方法
2018/12/08 Python
python 应用之Pycharm 新建模板默认添加编码格式-作者-时间等信息【推荐】
2019/06/17 Python
Tensorflow卷积实现原理+手写python代码实现卷积教程
2020/05/22 Python
瑞士网球商店:Tennis-Point
2020/03/12 全球购物
平面设计师的工作职责
2013/11/21 职场文书
金融保险专业求职信
2014/09/03 职场文书
2014年工作总结及2015工作计划
2014/12/12 职场文书
2015年度质量工作总结报告
2015/04/27 职场文书
公诉意见书范文
2015/06/05 职场文书
2016年大学迎新工作总结
2015/10/14 职场文书
史上最全的军训拉歌口号
2015/12/25 职场文书
Java SSH 秘钥连接mysql数据库的方法
2021/06/28 Java/Android