一文了解vue-router之hash模式和history模式


Posted in Javascript onMay 31, 2019

当前版本: 3.0.3

类目录: src/history/base.js

hash模式

即地址栏 URL 中的 # 符号(此 hash 不是密码学里的散列运算)。比如这个 URL: http://www.abc.com/#/hello ,hash 的值为 #/hello。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。

history模式

利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。

HTML5History实现

使用window.addEventListener('popstate')监听浏览器滚动行为,然后判断配置是否有scrollBehavior, 有就调用handleScroll方法来处理

滚动行为: 使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。 vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。

handleScroll

<!-- 等待页面渲染完才进行滚动的操作 -->
 router.app.$nextTick(() => {
   <!-- 初始化数据 -->
  const position = getScrollPosition()
  const shouldScroll = behavior.call(router, to, from, isPop ? position : null)

  if (!shouldScroll) {
   return
  }
  <!-- 判断是否是Promise,官网说支持异步 -->
  if (typeof shouldScroll.then === 'function') {
   shouldScroll.then(shouldScroll => {
    scrollToPosition((shouldScroll: any), position)
   }).catch(err => {
    if (process.env.NODE_ENV !== 'production') {
     assert(false, err.toString())
    }
   })
  } else {
   scrollToPosition(shouldScroll, position)
  }
 })

scrollToPosition

function scrollToPosition (shouldScroll, position) {
 const isObject = typeof shouldScroll === 'object'
 <!-- 对position进行初始化的操作 -->
 if (isObject && typeof shouldScroll.selector === 'string') {
  const el = document.querySelector(shouldScroll.selector)
  if (el) {
   let offset = shouldScroll.offset && typeof shouldScroll.offset === 'object' ? shouldScroll.offset : {}
   offset = normalizeOffset(offset)
   position = getElementPosition(el, offset)
  } else if (isValidPosition(shouldScroll)) {
   position = normalizePosition(shouldScroll)
  }
 } else if (isObject && isValidPosition(shouldScroll)) {
  position = normalizePosition(shouldScroll)
 }
  使用window.scrollTo来进行滚动处理
 if (position) {
  window.scrollTo(position.x, position.y)
 }
}

push

push操作也是 HTML5History模式下的一个比较关键的方法,他使用pushState来进行跳转操作,然后handleScroll来进行滚动\

export function pushState (url?: string, replace?: boolean) {
  <!-- 保存当前页面的滚动位置 -->
 saveScrollPosition()
 // try...catch the pushState call to get around Safari
 // DOM Exception 18 where it limits to 100 pushState calls
 const history = window.history
 try {
   <!-- 判断是哪种操作动作 -->
  if (replace) {
   history.replaceState({ key: _key }, '', url)
  } else {
   _key = genKey()
   history.pushState({ key: _key }, '', url)
  }
 } catch (e) {
  window.location[replace ? 'replace' : 'assign'](url)
 }
}

HashHistory实现

对于HashHistory的实现,和HTML5History的区别是在于Listener的方式和跳转的方式

Listener的方式这里是使用了hashchange,但是如果需要滚动行为就会去监听popstate

window.addEventListener(supportsPushState ? 'popstate' : 'hashchange')

跳转的方式会判断是否需要滚动,不需要就直接使用window.location.hash

function pushHash (path) {
 if (supportsPushState) {
  pushState(getUrl(path))
 } else {
  window.location.hash = path
 }
}

总结

以上所述是小编给大家介绍的vue-router之hash模式和history模式,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
让textarea控件的滚动条怎是位与最下方
Apr 20 Javascript
js DataSet数据源处理代码
Mar 29 Javascript
jQuery学习笔记之Helloworld
Dec 22 Javascript
js将控件隐藏及display属性的使用介绍
Dec 30 Javascript
jquery库或JS文件在eclipse下报错问题解决方法
Apr 17 Javascript
js控制当再次点击按钮时的间隔时间
Jun 03 Javascript
jQuery中noConflict()用法实例分析
Feb 08 Javascript
jquery ztree异步搜索(搜叶子)实践
Feb 25 Javascript
Jquery+ajax+JAVA(servlet)实现下拉菜单异步取值
Mar 23 Javascript
vue配置接口域名方法总结
May 12 Javascript
微信小程序tab切换可滑动切换导航栏跟随滚动实现代码
Sep 04 Javascript
bootstrap-paginator服务器端分页使用方法详解
Feb 13 Javascript
vue App.vue中的公共组件改变值触发其他组件或.vue页面监听
May 31 #Javascript
微信小程序环境下将文件上传到OSS的方法步骤
May 31 #Javascript
Vue Router history模式的配置方法及其原理
May 30 #Javascript
vue-cli3+ts+webpack实现多入口多出口功能
May 30 #Javascript
详解Vue项目引入CreateJS的方法(亲测可用)
May 30 #Javascript
了解JavaScript函数中的默认参数
May 30 #Javascript
Element-ui中元素滚动时el-option超出元素区域的问题
May 30 #Javascript
You might like
php MessagePack介绍
2013/10/06 PHP
PHP永久登录、记住我功能实现方法和安全做法
2015/04/27 PHP
PHP实现的简单网络硬盘
2015/07/29 PHP
jQuery ajax+PHP实现的级联下拉列表框功能示例
2019/02/12 PHP
php面向对象程序设计中self与static的区别分析
2019/05/21 PHP
php使用curl模拟多线程实现批处理功能示例
2019/07/25 PHP
JQuery 初体验(建议学习jquery)
2009/04/25 Javascript
解决jquery .ajax 在IE下卡死问题的解决方法
2009/10/26 Javascript
js 屏蔽鼠标右键脚本附破解方法
2009/12/03 Javascript
jQuery的写法不同导致的兼容性问题的解决方法
2010/07/29 Javascript
基于jquery创建的一个图片、视频缓冲的效果样式插件
2012/08/28 Javascript
JS、CSS加载中的小问题探讨
2013/11/26 Javascript
Jquery+asp.net后台数据传到前台js进行解析的方法
2014/05/11 Javascript
js实现汉字排序的方法
2015/07/23 Javascript
AngularJS入门教程之ng-checked 指令详解
2016/08/01 Javascript
js异步上传多张图片插件的使用方法
2018/10/22 Javascript
React父子组件间的传值的方法
2018/11/13 Javascript
javascript中join方法实例讲解
2019/02/21 Javascript
工作中常用js功能汇总
2020/11/07 Javascript
[06:16]第十四期-国士无双绝地翻盘之撼地神牛
2014/06/24 DOTA
Python中用于去除空格的三个函数的使用小结
2015/04/07 Python
jupyter notebook读取/导出文件/图片实例
2020/04/16 Python
用CSS3实现Win8风格的方格导航菜单效果
2013/04/10 HTML / CSS
纯CSS3发光分享按钮的实现教程
2014/09/06 HTML / CSS
在IE6系列等老式浏览器中使用HTML5的新标签实现方案
2012/12/25 HTML / CSS
Raleigh兰令自行车美国官网:英国凤头牌自行车
2018/01/08 全球购物
聪明的粉丝购买门票的地方:TickPick
2018/03/09 全球购物
Nº21官方在线商店:numeroventuno.com
2019/09/26 全球购物
初一学生期末评语
2014/04/24 职场文书
求职信范文大全
2014/05/26 职场文书
调研报告的主要写法
2019/04/18 职场文书
《雪域豹影》读后感:父爱的伟大
2019/12/23 职场文书
Nginx+SpringBoot实现负载均衡的示例
2021/03/31 Servers
修改并编译golang源码的操作步骤
2021/07/25 Golang
Nginx虚拟主机的搭建的实现步骤
2022/01/18 Servers
java项目构建Gradle的使用教程
2022/03/24 Java/Android