一文了解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 相关文章推荐
javascript 日期时间函数(经典+完善+实用)
May 27 Javascript
ExtJs Excel导出并下载IIS服务器端遇到的问题
Sep 16 Javascript
Jquery 点击按钮自动高亮实现原理及代码
Apr 25 Javascript
JavaScript实现cookie的写入、读取、删除功能
Nov 05 Javascript
javascript数据结构之双链表插入排序实例详解
Nov 25 Javascript
jQuery实现的网格线绘制方法
Jun 20 Javascript
jQuery实现优雅的弹窗效果(6)
Feb 08 Javascript
JS ES6多行字符串与连接字符串的表示方法
Apr 26 Javascript
ES6入门教程之let和const命令详解
May 17 Javascript
vue-resource + json-server模拟数据的方法
Nov 02 Javascript
用最少的JS代码写出贪吃蛇游戏
Jan 12 Javascript
cypress测试本地web应用
Jun 01 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
星际中一些鲜为人知的详细资料
2020/03/04 星际争霸
mysql5写入和读出乱码解决
2006/11/25 PHP
php文件打包 下载之使用PHP自带的ZipArchive压缩文件并下载打包好的文件
2012/06/13 PHP
PHP中使用json数据格式定义字面量对象的方法
2014/08/20 PHP
php中Array2xml类实现数组转化成XML实例
2014/12/08 PHP
Referer原理与图片防盗链实现方法详解
2019/07/03 PHP
关于Curl在Swoole协程中的解决方案详析
2019/09/12 PHP
破除一些网站复制、右键限制
2006/11/04 Javascript
javascript+dom树型菜单类,希望朋友们一起进步
2007/05/03 Javascript
web性能优化之javascript性能调优
2012/12/28 Javascript
JS教程:window.location使用方法的区别介绍
2013/10/04 Javascript
JS使用oumousemove和oumouseout动态改变图片显示的方法
2015/03/31 Javascript
javascript闭包的理解
2015/04/01 Javascript
微信js-sdk地理位置接口用法示例
2016/10/12 Javascript
BootStrap tooltip提示框使用小结
2016/10/26 Javascript
jquery插件bootstrapValidator数据验证详解
2016/11/09 Javascript
实例解析Array和String方法
2016/12/14 Javascript
Angular.Js中过滤器filter与自定义过滤器filter实例详解
2017/05/08 Javascript
使用Angular CLI从蓝本生成代码详解
2018/03/24 Javascript
详解Vue项目编译后部署在非网站根目录的解决方案
2018/04/26 Javascript
JavaScript实现shuffle数组洗牌操作示例
2019/01/03 Javascript
layer.confirm点击第一个按钮关闭弹出框的方法
2019/09/09 Javascript
python3.6使用pickle序列化class的方法
2018/10/22 Python
基于numpy中的expand_dims函数用法
2019/12/18 Python
Python sklearn中的.fit与.predict的用法说明
2020/06/28 Python
IE浏览器单独写CSS样式的几种方法
2014/10/14 HTML / CSS
Grid 宫格常用布局的实现
2020/01/10 HTML / CSS
HTML5 微格式和相关的属性名称
2010/02/10 HTML / CSS
详解html2canvas截图不能截取圆角图片的解决方案
2018/01/30 HTML / CSS
软件测试面试题
2015/10/21 面试题
党员干部2014全国两会学习心得体会
2014/03/10 职场文书
地下停车场租赁协议范本
2014/10/07 职场文书
人事局接收函
2015/01/31 职场文书
父亲节寄语大全
2015/02/27 职场文书
中学总务处工作总结
2015/08/12 职场文书
暑假开始了,你的暑假学习计划写好了吗?
2019/07/04 职场文书