一文了解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 单引号 传递方法
Jun 22 Javascript
Javascript获取HTML静态页面参数传递值示例
Aug 18 Javascript
实现动画效果核心方式的js代码
Sep 27 Javascript
js传中文参数controller里获取参数乱码问题解决方法
Jan 03 Javascript
使用OpenLayers3 添加地图鼠标右键菜单
Dec 29 Javascript
JSON 必知必会 观后记
Oct 27 Javascript
ES6中module模块化开发实例浅析
Apr 06 Javascript
深入理解react-router@4.0 使用和源码解析
May 23 Javascript
Javascript别踩白块儿(钢琴块儿)小游戏实现代码
Jul 20 Javascript
通过vue-cli3构建一个SSR应用程序的方法
Sep 13 Javascript
在微信小程序中渲染HTML内容的方法示例
Sep 28 Javascript
webpack是如何实现模块化加载的方法
Nov 06 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
BBS(php &amp; mysql)完整版(五)
2006/10/09 PHP
PHP之生成GIF动画的实现方法
2013/06/07 PHP
php使用array_rand()函数从数组中随机选择一个或多个元素
2014/04/28 PHP
JavaScript arguments 多参传值函数
2010/10/24 Javascript
Dom在ajax技术中的作用说明
2010/10/25 Javascript
自定义右键属性覆盖浏览器默认右键行为实现代码
2013/02/02 Javascript
jquery 漂亮的删除确认和提交无刷新删除示例
2013/11/13 Javascript
快速解决FusionCharts联动的中文乱码问题
2013/12/04 Javascript
Javascript 读取操作Sql中的Xml字段
2014/10/09 Javascript
JavaScript中setMonth()方法的使用详解
2015/06/11 Javascript
jQuery Ajax Post 回调函数不执行问题的解决方法
2016/08/15 Javascript
nodejs简单实现操作arduino
2016/09/25 NodeJs
javascript稀疏数组(sparse array)和密集数组用法分析
2016/12/28 Javascript
vue页面使用阿里oss上传功能的实例(一)
2017/08/09 Javascript
Angularjs中数据绑定的实例详解
2017/08/25 Javascript
原生JS上传大文件显示进度条 php上传文件代码
2020/03/27 Javascript
[04:30]显微镜下的DOTA2第五期——拉比克
2013/09/26 DOTA
[01:32:22]DOTA2-DPC中国联赛 正赛 Ehome vs VG BO3 第一场 2月5日
2021/03/11 DOTA
python读取excel表格生成erlang数据
2017/08/26 Python
Python3利用SMTP协议发送E-mail电子邮件的方法
2017/09/30 Python
python爬虫headers设置后无效的解决方法
2017/10/21 Python
python高级特性和高阶函数及使用详解
2018/10/17 Python
使用django和vue进行数据交互的方法步骤
2019/11/11 Python
如何基于python操作json文件获取内容
2019/12/24 Python
pytorch中获取模型input/output shape实例
2019/12/30 Python
Python3爬虫mitmproxy的安装步骤
2020/07/29 Python
three.js模拟实现太阳系行星体系功能
2019/09/03 HTML / CSS
Seavenger官网:潜水服、浮潜、靴子和袜子
2020/03/05 全球购物
工商技校毕业生自荐信
2013/11/15 职场文书
银行实习的自我鉴定
2013/12/10 职场文书
爷爷追悼会答谢词
2014/01/24 职场文书
土建专业大学生自荐信范文
2014/04/09 职场文书
小学生综合素质评语
2014/04/23 职场文书
工商管理专业毕业生求职信
2014/05/26 职场文书
观后感开头
2015/06/19 职场文书
2019年国庆祝福语(70句)
2019/09/19 职场文书