一文了解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 相关文章推荐
Opacity.js
Jan 22 Javascript
经常用的图片在容器中的水平垂直居中实例
Jun 10 Javascript
js document.write()使用介绍
Feb 21 Javascript
jquery实现可横向和竖向展开的动态下滑菜单效果
Aug 24 Javascript
bootstrap日历插件datetimepicker使用方法
Dec 14 Javascript
JavaScript数据结构之二叉树的查找算法示例
Apr 13 Javascript
使用nvm管理不同版本的node与npm的方法
Oct 31 Javascript
JavaScript屏蔽Backspace键的实现代码
Nov 02 Javascript
JavaScript学习总结(一) ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)
Jan 07 Javascript
原生js封装的ajax方法示例
Aug 02 Javascript
解决vue 单文件组件中样式加载问题
Apr 24 Javascript
Vue-drag-resize 拖拽缩放插件的使用(简单示例)
Dec 04 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
zen_cart实现支付前生成订单的方法
2016/05/06 PHP
php+iframe 实现上传文件功能示例
2020/03/04 PHP
用php实现分页效果的示例代码
2020/12/10 PHP
Javascript miscellanea -display data real time, using window.status
2007/01/09 Javascript
写的htc的数据表格
2007/01/20 Javascript
in.js 一个轻量级的JavaScript颗粒化模块加载和依赖关系管理解决方案
2011/07/26 Javascript
读jQuery之十四 (触发事件核心方法)
2011/08/23 Javascript
JS特权方法定义作用以及与公有方法的区别
2013/03/18 Javascript
jquery中交替点击事件toggle方法的使用示例
2013/12/08 Javascript
详解JavaScript中|单竖杠运算符的使用方法
2016/05/23 Javascript
jQuery中的on与bind绑定事件区别实例详解
2017/02/28 Javascript
JS二分查找算法详解
2017/11/01 Javascript
Vue无限滑动周选择日期的组件的示例代码
2018/07/18 Javascript
最简单的JS实现json转csv的方法
2019/01/10 Javascript
JavaScript使用闭包模仿块级作用域操作示例
2019/01/21 Javascript
vue 使用鼠标滚动加载数据的例子
2019/10/31 Javascript
vue 判断两个时间插件结束时间必选大于开始时间的代码
2020/11/04 Javascript
推荐11个实用Python库
2015/01/23 Python
python MySQLdb Windows下安装教程及问题解决方法
2015/05/09 Python
python 简单的绘图工具turtle使用详解
2017/06/21 Python
Python多线程中阻塞(join)与锁(Lock)使用误区解析
2018/04/27 Python
python使用Flask操作mysql实现登录功能
2018/05/14 Python
Django框架首页和登录页分离操作示例
2019/05/28 Python
matplotlib命令与格式之tick坐标轴日期格式(设置日期主副刻度)
2019/08/06 Python
Atom Python 配置Python3 解释器的方法
2019/08/28 Python
python pygame实现滚动横版射击游戏城市之战
2019/11/25 Python
Python API len函数操作过程解析
2020/03/05 Python
Anaconda+vscode+pytorch环境搭建过程详解
2020/05/25 Python
详解通过HTML5 Canvas实现图片的平移及旋转变化的方法
2016/03/22 HTML / CSS
营业员演讲稿
2013/12/30 职场文书
五一劳动节演讲稿
2014/09/12 职场文书
党员批评与自我批评发言稿
2014/10/14 职场文书
大学生逃课检讨书
2015/05/04 职场文书
2015暑期社会实践调查报告
2015/07/14 职场文书
2015年支教教师工作总结
2015/07/22 职场文书
世界十大动漫制作公司排行榜,迪士尼上榜,第二是美国代表性文化符
2022/03/18 欧美动漫