一文了解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 相关文章推荐
通过JAVASCRIPT读取ASP设定的COOKIE
Nov 24 Javascript
javascript Split方法,indexOf方法、lastIndexOf 方法和substring 方法
Mar 21 Javascript
浏览器的JavaScript引擎的识别方法
Oct 20 Javascript
js 事件截取enter按键页面提交事件示例代码
Mar 04 Javascript
javascript获取dom的下一个节点方法
Sep 05 Javascript
如何在MVC应用程序中使用Jquery
Nov 17 Javascript
jQuery中$.get、$.post、$.getJSON和$.ajax的用法详解
Nov 19 Javascript
javascript中Array数组的迭代方法实例分析
Feb 04 Javascript
JS版元素周期表实现方法
Aug 05 Javascript
node.js回调函数之阻塞调用与非阻塞调用
Nov 13 Javascript
详谈Angular 2+ 的表单(一)之模板驱动型表单
Apr 25 Javascript
vue路由守卫+登录态管理实例分析
May 21 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/03 新手入门
根据分辨率不同,调用不同的css文件
2006/08/25 Javascript
取得传值的函数
2006/10/27 Javascript
一段好玩的JavaScript代码
2006/12/01 Javascript
利用函数的惰性载入提高javascript代码执行效率
2014/05/05 Javascript
基于canvas实现的钟摆效果完整实例
2016/01/26 Javascript
EXT中单击button按钮grid添加一行(光标位置可设置)的实例代码
2016/06/02 Javascript
浅谈JS之iframe中的窗口
2016/09/13 Javascript
jQuery实现背景滑动菜单
2016/12/02 Javascript
vue中的scope使用详解
2017/10/29 Javascript
搭建基于express框架运行环境的方法步骤
2018/11/15 Javascript
基于element-ui组件手动实现单选和上传功能
2018/12/06 Javascript
viewer.js实现图片预览功能
2020/06/24 Javascript
Vue父组件监听子组件生命周期
2020/09/03 Javascript
Python实现螺旋矩阵的填充算法示例
2017/12/28 Python
Python实现基于TCP UDP协议的IPv4 IPv6模式客户端和服务端功能示例
2018/03/22 Python
python实现任意位置文件分割的实例
2018/12/14 Python
python3实现钉钉消息推送的方法示例
2019/03/14 Python
python超时重新请求解决方案
2019/10/21 Python
Python创建一个元素都为0的列表实例
2019/11/28 Python
在PyCharm中实现添加快捷模块
2020/02/12 Python
用python写爬虫简单吗
2020/07/28 Python
matplotlib基础绘图命令之errorbar的使用
2020/08/13 Python
Python中免验证跳转到内容页的实例代码
2020/10/23 Python
Python实现Excel自动分组合并单元格
2021/02/22 Python
pytorch Dataset,DataLoader产生自定义的训练数据案例
2021/03/03 Python
详解如何在css3打包后自动追加前缀插件:autoprefixer
2018/12/18 HTML / CSS
迪卡侬比利时官网:Decathlon比利时
2019/12/28 全球购物
以下为Windows NT 下的32 位C++程序,请计算sizeof 的值
2016/12/07 面试题
Unix控制后台进程都有哪些进程
2016/09/22 面试题
社区工作者思想汇报
2014/01/13 职场文书
党员四风问题对照检查材料
2014/09/27 职场文书
个人创业事迹材料
2014/12/30 职场文书
清明祭英烈活动总结
2015/05/11 职场文书
《半截蜡烛》教学反思
2016/02/19 职场文书
MySQL中几种插入和批量语句实例详解
2021/09/14 MySQL