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 相关文章推荐
如何正确解决VuePress本地访问出现资源报错404的问题
Dec 03 Vue.js
详解Vue的异步更新实现原理
Dec 22 Vue.js
vue+vant 上传图片需要注意的地方
Jan 03 Vue.js
vue动态设置路由权限的主要思路
Jan 13 Vue.js
vue仿携程轮播图效果(滑动轮播,下方高度自适应)
Feb 11 Vue.js
Vue+Element UI实现概要小弹窗的全过程
May 30 Vue.js
vue响应式原理与双向数据的深入解析
Jun 04 Vue.js
详解Vue的列表渲染
Nov 20 Vue.js
Vue.js中v-bind指令的用法介绍
Mar 13 Vue.js
vue中的可拖拽宽度div的实现示例
Apr 08 Vue.js
vue二维数组循环嵌套方式 循环数组、循环嵌套数组
Apr 24 Vue.js
vue3 自定义图片放大器效果的示例代码
Jul 23 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
推荐几部必看的DC动画电影
2020/03/03 欧美动漫
人族 Terran 魔法与科技
2020/03/14 星际争霸
十天学会php之第七天
2006/10/09 PHP
深入PHP中慎用双等于(==)的详解
2013/06/06 PHP
Win2003+apache+PHP+SqlServer2008 配置生产环境
2014/07/29 PHP
PHP实现小偷程序实例
2016/10/31 PHP
详解PHP变量传值赋值和引用赋值变量销毁
2019/03/23 PHP
在textarea文本域中显示HTML代码的方法
2007/03/06 Javascript
两个JavaScript jsFiddle JSBin在线调试器
2010/03/14 Javascript
jQuery实现动画效果的简单实例
2014/01/27 Javascript
js清空表单数据的两种方式(遍历+reset)
2014/07/18 Javascript
最简单的JavaScript验证整数、小数、实数、有效位小数正则表达式
2015/04/17 Javascript
jQuery获取及设置表单input各种类型值的方法小结
2016/05/24 Javascript
原生js仿淘宝网商品放大镜效果
2017/02/28 Javascript
NodeJS、NPM安装配置步骤(windows版本) 以及环境变量详解
2017/05/13 NodeJs
Three.js实现绘制字体模型示例代码
2017/09/26 Javascript
详解在WebStorm中添加Vue.js单文件组件的高亮及语法支持
2017/10/21 Javascript
vue添加axios,并且指定baseurl的方法
2018/09/19 Javascript
vue 插槽简介及使用示例
2020/11/19 Vue.js
Python 自动安装 Rising 杀毒软件
2009/04/24 Python
对命令行模式与python交互模式介绍
2018/05/12 Python
python使用turtle绘制分形树
2018/06/22 Python
Python lambda表达式用法实例分析
2018/12/25 Python
python获取当前文件路径以及父文件路径的方法
2019/07/10 Python
python使用Pandas库提升项目的运行速度过程详解
2019/07/12 Python
Python基础之列表常见操作经典实例详解
2020/02/26 Python
pycharm中如何自定义设置通过“ctrl+滚轮”进行放大和缩小实现方法
2020/09/16 Python
CSS3使用transition实现的鼠标悬停淡入淡出
2015/01/09 HTML / CSS
CSS3实现网站商品展示效果图
2020/01/18 HTML / CSS
新西兰最大的在线设计师眼镜店:SmartBuyGlasses新西兰
2017/10/20 全球购物
汉森冲浪板:Hansen Surfboards
2018/05/19 全球购物
分别介绍一下Session Bean和Entity Bean
2015/03/13 面试题
电钳专业个人求职信
2014/01/04 职场文书
消防标语大全
2014/06/07 职场文书
上班旷工检讨书
2015/08/15 职场文书
python实现简单的三子棋游戏
2022/04/28 Python