重识Vue路由两种模式-hash和history

vue-router的工作原理

单页面应用(SPA)的核心思想之一,就是更新视图而不重新请求页面,简单来说,它在加载页面时,不会加载整个页面,只会更新某个指定的容器中的内容。对于大多数单页面应用,都推荐使用官方支持的vue-router。

在实现单页面前端路由时,提供了两种方式,分别是hash模式和history模式,根据mode参数来决定采用哪一种方式。

hash和history的区别

hash模式的url后跟hash值#…,它的原理就是使用window.onHashChange来监听hash值的改变,一旦发生变化就找出此hash值所匹配的组件,进而将组件渲染到页面中。但是hash模式这种带hash值的url是非常丑的,项目中也很少用hash模式。

history模式中的url是以/user这种格式,比较常见,它的原理是通过window.onpopstate来监听路由变化,进而匹配不同的组件来渲染出来。

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

hash模式

hash 就是指 url 尾巴后的 # 号以及后面的字符。这里的 # 和 css 里的 # 是一个意思。hash 也称作锚点,本身是用来做页面定位的,他可以使对应 id 的元素显示在可视区域内。在url后面加上#,如http://127.0.0.1:5500/前端路由/hash.html#/page1这个url后面的#/page1就是hash值

hash主要是一个事件:hashchange,当hash值改变时会触发这个事件,语法:window.onhashchange = fun,或者:

  • hash 值的变化不会导致浏览器像服务器发送请求
  • location.hash可以获取hash值
  • hashchange是hash值发生改变的调用的函数
window.location.hash = 'qq' // 设置 url 的 hash,会在当前url后加上 '#qq'
var hash = window.location.hash // '#qq'  
window.addEventListener('hashchange', function(){ 
  // do something
})
history模式

要查看此 API 的功能,只需进入开发人员工具并history在控制台中输入即可。如果您选择的浏览器支持该 API,那么我们将找到许多附加到该对象的方法:

history基本api:

  • history.go(n):路由跳转几步,n为2往前跳转2个页面,-2往后跳转两个页面
  • history.back():路由后退,相当于 history.go(-1),用户可点击浏览器左上角的后退按钮模拟此方法
  • history.forward():路由前进,相当于 history.go(1),用户可点击浏览器左上角的前进按钮模拟此方法

history.replaceState()

history.replaceState(null, null, 'hello');

上面的replaceState方法用“/hello”切换地址栏中的 URL,尽管没有请求资产并且窗口保持在同一页面上。然而这里有一个问题。点击返回按钮后,我们会发现我们并没有返回到本文的 URL,而是返回到之前的任何页面。这是因为replaceState不操纵浏览器的历史,它只是替换地址栏中的当前 URL。为了解决这个问题,我们需要使用以下pushState方法:

history.pushState(): 添加一条路由历史记录,如果设置跨域网址则报错

history.pushState用于在浏览历史中添加历史记录,但是并不触发跳转,此方法接受三个参数:

  • state:一个与指定网址相关的状态对象,popstate事件触发时,该对象会传入回调函数。如果不需要这个对象,此处可以填null。
  • title:新页面的标题,但是所有浏览器目前都忽略这个值,因此这里可以填null。
  • url:新的网址,必须与当前页面处在同一个域。浏览器的地址栏将显示这个网址。
history.pushState(null, null, 'hello');

现在,如果我们单击后退按钮,我们应该会发现它按我们希望的方式工作,因为pushState已经更改了我们的历史记录以包含我们刚刚传递给它的任何 URL。

popState 事件
每当同一个文档的浏览历史(即history)出现变化时,就会触发popState事件。
注意:仅仅调用pushState方法或replaceState方法,并不会触发该事件,只有用户点击浏览器后退和前进按钮时,或者使用js调用back、forward、go方法时才会触发。另外该事件只针对同一个文档,如果浏览历史的切换,导致加载不同的文档,该事件不会被触发
使用的时候,可以为popState事件指定回调函数

window.onpopstate = function (event) {
  console.log('location: ' + document.location);
  console.log('state: ' +JSON.stringify(event.state));
};
// 或者
window.addEventListener('popstate', function(event) {
  console.log('location: ' + document.location);
  console.log('state: ' + JSON.stringify(event.state));
});

注意:页面第一次加载的时候,浏览器不会触发popState事件

vue-router中history和hash两种模式的区别

在vue的路由配置中有mode选项 最直观的区别就是在url中hash带了一个很丑的#,而history是没有#的

hash和history模式的不同: 对于vue这类渐进式的前端开发框架,为了构建spa单页面应用,需要引入前端路由系统,也就是vue-router存在的意义。前端路由的核心就在于—改变视图的同时不会向后端发出请求。为了达到这一目的,浏览器提供了以下两种支持:

  • hash-----即地址栏url中的#符号,比如:http://www.baidu.com/#/a,hash…。它的特点在于#/a虽然在url中,但不会被包括在http请求中,对后端完全没有影响,因此改变hash不会重新加载页面。
  • history-----利用了html5 History Interface中新增的pushState()和replaceState()方法。这两个方法应用于浏览器的历史记录栈,在当前已有的back、forward、go的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的url,但浏览器不会立即向后端发送请求。

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

调用history.pushState()相比于直接修改hash,存在以下优势:

  • pushState()设置的新的url可以是于当前url同源的任意url,而hash只可修改#后面的部分,因此只能设置与当亲url同文档的url
  • pushState()设置的新的url可以与当前url一摸一样,这样也会把记录添加到栈中;而hash设置的新值必须与原来的不一样才会触发动作将记录添加到栈中
  • pushState()通过stateObject参数可以添加任意类型的数据到记录中;而hash只可添加短字符串
  • pushState()可额外设置title属性提供后续使用
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值