一文了解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 相关文章推荐
Mozilla中显示textarea中选择的文字
Sep 07 Javascript
解析jQuery与其它js(Prototype)库兼容共存
Jul 04 Javascript
js的隐含参数(arguments,callee,caller)使用方法
Jan 28 Javascript
jquery图片轮播特效代码分享
Apr 20 Javascript
Axios学习笔记之使用方法教程
Jul 21 Javascript
解决ie img标签内存泄漏的问题
Oct 13 Javascript
通过一个简单的例子学会vuex与模块化
Nov 22 Javascript
JavaScript通过mouseover()实现图片变大效果的示例
Dec 20 Javascript
基于jquery的on和click的区别详解
Jan 15 jQuery
解决mpvue + vuex 开发微信小程序vuex辅助函数mapState、mapGetters不可用问题
Aug 03 Javascript
ES6常用小技巧总结【去重、交换、合并、反转、迭代、计算等】
Dec 21 Javascript
vue.js使用v-model实现父子组件间的双向通信示例
Feb 05 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
一个简单计数器的源代码
2006/10/09 PHP
使用PHP实现阻止用户上传成人照片或者裸照
2014/12/25 PHP
php中使用gd库实现下载网页中所有图片
2015/05/12 PHP
php实现贪吃蛇小游戏
2016/07/26 PHP
PHP回调函数与匿名函数实例详解
2017/08/16 PHP
laravel框架中视图的基本使用方法分析
2019/11/23 PHP
多个iframe自动调整大小的问题
2006/09/18 Javascript
javascript深入理解js闭包
2010/07/03 Javascript
JavaScript实现关键字高亮功能
2014/11/12 Javascript
jQuery中的编程范式详解
2014/12/15 Javascript
JavaScript转换二进制编码为ASCII码的方法
2015/04/16 Javascript
jQuery中$.extend()用法实例
2015/06/24 Javascript
浅谈React中的元素、组件、实例和节点
2018/02/27 Javascript
Angular动画实现的2种方式以及添加购物车动画实例代码
2018/08/09 Javascript
解决layui上传文件提示上传异常,实际文件已经上传成功的问题
2018/08/19 Javascript
js键盘事件实现人物的行走
2020/01/17 Javascript
解决vue一个页面中复用同一个echarts组件的问题
2020/07/19 Javascript
Vue 请求传公共参数的操作
2020/07/31 Javascript
vue打开其他项目页面并传入数据详解
2020/11/25 Vue.js
[01:01:18]VP vs NIP 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Anaconda多环境多版本python配置操作方法
2017/09/12 Python
浅析Python装饰器以及装饰器模式
2018/05/28 Python
python 找出list中最大或者最小几个数的索引方法
2018/10/30 Python
python中的split()函数和os.path.split()函数使用详解
2019/12/21 Python
Python3 读取Word文件方式
2020/02/13 Python
python中的 zip函数详解及用法举例
2020/02/16 Python
Jupyter notebook命令和编辑模式常用快捷键汇总
2020/11/17 Python
python的setattr函数实例用法
2020/12/16 Python
英国领先的高街书籍专家:Waterstones
2018/02/01 全球购物
HttpServlet类中的主要方法都有哪些?各自的作用是什么?
2014/03/16 面试题
高中毕业自我鉴定
2013/12/16 职场文书
电焊工工作岗位职责
2014/02/06 职场文书
正科级干部考察材料
2014/05/29 职场文书
领导干部学习三严三实心得体会
2016/01/05 职场文书
咖啡厅里的创业计划书
2019/08/21 职场文书
MySQL学习之基础操作总结
2022/03/19 MySQL