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 插槽简介及使用示例
Nov 19 Vue.js
Vue.js桌面端自定义滚动条组件之美化滚动条VScroll
Dec 01 Vue.js
vue3.0+vue-router+element-plus初实践
Dec 02 Vue.js
实用的 vue tags 创建缓存导航的过程实现
Dec 03 Vue.js
Vue如何实现验证码输入交互
Dec 07 Vue.js
Vue与React的区别和优势对比
Dec 18 Vue.js
Vue3 实现双盒子定位Overlay的示例
Dec 22 Vue.js
vscode自定义vue模板的实现
Jan 27 Vue.js
vue脚手架项目创建步骤详解
Mar 02 Vue.js
Vue-router编程式导航的两种实现代码
Mar 04 Vue.js
如何用vue实现网页截图你知道吗
Nov 17 Vue.js
vue-treeselect的基本用法以及解决点击无法出现拉下菜单
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-fpm 参数的深入理解
2013/06/03 PHP
php实现httpclient类示例
2014/04/08 PHP
php中heredoc与nowdoc介绍
2014/12/25 PHP
thinkPHP5.1框架路由::get、post请求简单用法示例
2019/05/06 PHP
关于JavaScript中的关联数组分析
2013/04/09 Javascript
javascript获取元素CSS样式代码示例
2013/11/28 Javascript
JavaScript+html5 canvas绘制渐变区域完整实例
2016/01/26 Javascript
JavaScript实现多种排序算法
2016/02/24 Javascript
Javascript oop设计模式 面向对象编程简单实例介绍
2016/12/13 Javascript
jQuery实现QQ空间汉字转拼音功能示例
2017/07/10 jQuery
vue动态路由实现多级嵌套面包屑的思路与方法
2017/08/16 Javascript
详解webpack-dev-server使用方法
2018/09/14 Javascript
浅谈JavaScript中this的指向更改
2020/07/28 Javascript
python计算最小优先级队列代码分享
2013/12/18 Python
python使用新浪微博api上传图片到微博示例
2014/01/10 Python
python 的列表遍历删除实现代码
2020/04/12 Python
Python实现针对含中文字符串的截取功能示例
2017/09/22 Python
python机器学习理论与实战(五)支持向量机
2018/01/19 Python
利用python对Excel中的特定数据提取并写入新表的方法
2018/06/14 Python
使用Django简单编写一个XSS平台的方法步骤
2019/03/25 Python
Pandas DataFrame数据的更改、插入新增的列和行的方法
2019/06/25 Python
Python Django框架防御CSRF攻击的方法分析
2019/10/18 Python
Python中私有属性的定义方式
2020/03/05 Python
python实现程序重启和系统重启方式
2020/04/16 Python
纯CSS3+DIV实现小三角形边框效果的示例代码
2020/08/03 HTML / CSS
校园报刊亭的创业计划书
2014/01/02 职场文书
老同学聚会感言
2014/02/23 职场文书
出纳试用期自我鉴定
2014/04/07 职场文书
2014年保卫工作总结
2014/12/05 职场文书
公司2014年度工作总结
2014/12/10 职场文书
募捐感谢信
2015/01/22 职场文书
考试作弊检讨书范文
2015/01/27 职场文书
2015年村计划生育工作总结
2015/04/28 职场文书
《雪地里的小画家》教学反思
2016/02/16 职场文书
Java8中接口的新特性使用指南
2021/11/01 Java/Android
Windows Server 2012配置DNS服务器的方法
2022/04/29 Servers