一文了解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 相关文章推荐
完整显示当前日期和时间的JS代码
Sep 17 Javascript
jQuery表格列宽可拖拽改变且兼容firfox
Sep 03 Javascript
jQuery中:not选择器用法实例
Dec 30 Javascript
javascript实现Table间隔色以及选择高亮(和动态切换数据)的方法
May 14 Javascript
JQuery EasyUI学习教程之datagrid 添加、修改、删除操作
Jul 09 Javascript
微信小程序 ES6Promise.all批量上传文件实现代码
Apr 14 Javascript
jQuery插件ImgAreaSelect实现头像上传预览和裁剪功能实例讲解一
May 26 jQuery
js防刷新的倒计时代码 js倒计时代码
Sep 06 Javascript
vue生成token保存在客户端localStorage中的方法
Oct 25 Javascript
详解vuex的简单使用
Mar 12 Javascript
AJAX XMLHttpRequest对象创建使用详解
Aug 20 Javascript
通过高德地图API获得某条道路上的所有坐标用于描绘道路的方法
Aug 24 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
咖啡是不是喝了会上瘾?咖啡是必须品吗!
2021/03/04 新手入门
解析php中的escape函数
2013/06/29 PHP
php中instanceof 与 is_a()区别分析
2015/03/03 PHP
PHP中常见的缓存技术实例分析
2015/09/23 PHP
thinkPHP导出csv文件及用表格输出excel的方法
2015/12/30 PHP
PHP未登录自动跳转到登录页面
2016/12/21 PHP
使用PHP json_decode可能遇到的坑与解决方法
2017/08/03 PHP
PHP给源代码加密的几种方法汇总(推荐)
2018/02/06 PHP
Laravel5框架添加自定义辅助函数的方法
2018/08/01 PHP
setTimeout和setInterval的区别你真的了解吗?
2011/03/31 Javascript
JavaScript 更严格的相等 [译]
2012/09/20 Javascript
js螺旋动画效果的具体实例
2013/11/15 Javascript
谈谈encodeURI和encodeURIComponent以及escape的区别与应用
2015/11/24 Javascript
javascript淘宝主图放大镜功能
2016/10/20 Javascript
老生常谈的跨域处理
2017/01/11 Javascript
JavaScript的事件机制详解
2017/01/17 Javascript
详解Vue.js搭建路由报错 router.map is not a function
2017/06/27 Javascript
javascript基于定时器实现进度条功能实例
2017/10/13 Javascript
JavaScript判断数据类型有几种方法及区别介绍
2020/09/02 Javascript
[05:08]第一届“网鱼杯”DOTA2比赛精彩集锦
2014/09/05 DOTA
python判断一个集合是否包含了另外一个集合中所有项的方法
2015/06/30 Python
python清除字符串里非数字字符的方法
2015/07/02 Python
详解Python设计模式编程中观察者模式与策略模式的运用
2016/03/02 Python
将tensorflow的ckpt模型存储为npy的实例
2018/07/09 Python
kafka-python批量发送数据的实例
2018/12/27 Python
Python实现的旋转数组功能算法示例
2019/02/23 Python
Python解压 rar、zip、tar文件的方法
2019/11/19 Python
python代码实现将列表中重复元素之间的内容全部滤除
2020/05/22 Python
深入理解Python变量的数据类型和存储
2021/02/01 Python
Ted Baker英国官网:男士和女士服装及配件
2017/03/13 全球购物
实习求职信
2013/12/01 职场文书
行政助理岗位职责范文
2013/12/03 职场文书
大学新生军训方案
2014/05/03 职场文书
网上祭先烈心得体会
2014/09/01 职场文书
公务员考察材料范文
2014/12/23 职场文书
2015世界地球日活动总结
2015/02/09 职场文书