一文了解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 相关文章推荐
Highslide.js是一款基于js实现的网页中图片展示插件
Mar 30 Javascript
多浏览器兼容性比较好的复制到剪贴板的js代码
Oct 09 Javascript
Javascript的各种节点操作实例演示代码
Jun 27 Javascript
图标线性回归斜着移动到指定的位置
Aug 16 Javascript
js获取select标签的值且兼容IE与firefox
Dec 30 Javascript
asp.net中oracle 存储过程(图文)
Aug 12 Javascript
js实现索引图片切换效果
Nov 21 Javascript
angular.js分页代码的实例
Jul 27 Javascript
使用vue.js实现联动效果的示例代码
Jan 10 Javascript
js断点调试经验分享
Dec 08 Javascript
Node.js在图片模板上生成二维码图片并附带底部文字说明实现详解
Aug 07 Javascript
p5.js临摹旋转爱心
Oct 23 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
IIS下PHP连接数据库提示mysql undefined function mysql_connect()
2010/06/04 PHP
深入PHP中慎用双等于(==)的详解
2013/06/06 PHP
使用php实现截取指定长度
2013/08/06 PHP
PHP仿微信发红包领红包效果
2016/10/30 PHP
jQuery chili图片远处放大插件
2009/11/30 Javascript
腾讯的ip接口 方便获取当前用户的ip地理位置
2010/11/25 Javascript
jquery 笔记 事件
2011/11/02 Javascript
让AJAX不依赖后端接口实现方案
2012/12/03 Javascript
jQuery渐变发光导航菜单的实例代码
2013/03/27 Javascript
javascript中scrollTop详解
2015/04/13 Javascript
jquery UI Datepicker时间控件的使用方法(终结版)
2015/11/07 Javascript
AngularJS仿苹果滑屏删除控件
2016/01/18 Javascript
jQuery+canvas实现简单的球体斜抛及颜色动态变换效果
2016/01/28 Javascript
jQuery 获取多选框的值及多选框中文的函数
2016/05/16 Javascript
JS控制静态页面传递参数并获取参数应用
2016/08/10 Javascript
JavaScript正则表达式小结(test|match|search|replace|split|exec)
2016/12/08 Javascript
checkbox在vue中的用法小结
2018/11/13 Javascript
node错误处理与日志记录的实现
2018/12/24 Javascript
超轻量级的js时间库miment使用解析
2019/08/02 Javascript
vue解决使用$http获取数据时报错的问题
2019/10/30 Javascript
node.JS的crypto加密模块使用方法详解(MD5,AES,Hmac,Diffie-Hellman加密)
2020/02/06 Javascript
单线程JavaScript实现异步过程详解
2020/05/19 Javascript
Echarts.js无法引入问题解决方案
2020/10/30 Javascript
[02:00]DAC2018主宣传片——龙征四海,剑问东方
2018/03/20 DOTA
python显示生日是星期几的方法
2015/05/27 Python
Python实现程序判断季节的代码示例
2019/01/28 Python
Flask使用Pyecharts在单个页面展示多个图表的方法
2019/08/05 Python
python多进程并发demo实例解析
2019/12/13 Python
全网最详细的PyCharm+Anaconda的安装过程图解
2021/01/25 Python
如何用 Python 制作一个迷宫游戏
2021/02/25 Python
css3 旋转按钮 使用CSS3创建一个旋转可变色按钮
2012/12/31 HTML / CSS
运动会100米解说词
2014/01/23 职场文书
销售个人求职信范文
2014/04/28 职场文书
上学路上观后感
2015/06/16 职场文书
三八妇女节致辞
2015/07/31 职场文书
全国劳模先进事迹材料(2016精选版)
2016/02/25 职场文书