一文了解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 相关文章推荐
node.js中的path.delimiter方法使用说明
Dec 09 Javascript
JS中prototype的用法实例分析
Mar 19 Javascript
jquery使用animate方法实现控制元素移动
Mar 27 Javascript
javascript实现简单的省市区三级联动
May 14 Javascript
JavaScript转换与解析JSON方法实例详解
Nov 24 Javascript
基于JavaScript实现div层跟随滚动条滑动
Jan 12 Javascript
jQuery插件HighCharts实现的2D对数饼图效果示例【附demo源码下载】
Mar 09 Javascript
微信小程序 在线支付功能的实现
Mar 14 Javascript
详解用node搭建简单的静态资源管理器
Aug 09 Javascript
vue在手机中通过本机IP地址访问webApp的方法
Aug 15 Javascript
JavaScript遍历DOM元素的常见方式示例
Feb 16 Javascript
微信小程序的线程架构【推荐】
May 14 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
PHP中的多行字符串传递给JavaScript的两种方法
2014/06/19 PHP
PHP基于CURL进行POST数据上传实例
2014/11/10 PHP
Laravel网站打开速度优化的方法汇总
2017/07/16 PHP
基于PHP的加载类操作以及其他两种魔术方法的应用实例
2017/08/28 PHP
php设计模式之享元模式分析【星际争霸游戏案例】
2020/03/23 PHP
ExtJS 设置级联菜单的默认值
2010/06/13 Javascript
基于jquery的二级联动菜单实现代码
2011/04/25 Javascript
Jquery绑定事件(bind和live的区别介绍)
2013/08/23 Javascript
你未必知道的JavaScript和CSS交互的5种方法
2014/04/02 Javascript
根据user-agent判断蜘蛛代码黑帽跳转代码(js版与php版本)
2015/09/14 Javascript
JS制作类似选项卡切换的年历
2016/12/03 Javascript
jQuery插件HighCharts实现气泡图效果示例【附demo源码】
2017/03/13 Javascript
node.js连接MongoDB数据库的2种方法教程
2017/05/17 Javascript
微信小程序实现验证码获取倒计时效果
2018/02/08 Javascript
JS构造一个html文本内容成文件流形式发送到后台
2018/07/31 Javascript
js中获取URL参数的共用方法getRequest()方法实例详解
2018/10/24 Javascript
VUE-ElementUI 自定义Loading图操作
2020/11/11 Javascript
[02:48]DOTA2英雄基础教程 拉席克
2013/12/12 DOTA
python 字典(dict)遍历的四种方法性能测试报告
2014/06/25 Python
Python微信公众号开发平台
2018/01/25 Python
Selenium 模拟浏览器动态加载页面的实现方法
2018/05/16 Python
Pycharm无法显示动态图片的解决方法
2018/10/28 Python
python中time库的实例使用方法
2019/10/31 Python
Flask项目中实现短信验证码和邮箱验证码功能
2019/12/05 Python
Python如何使用内置库matplotlib绘制折线图
2020/02/24 Python
后端开发使用pycharm的技巧(推荐)
2020/03/27 Python
python数据分析工具之 matplotlib详解
2020/04/09 Python
python3中的logging记录日志实现过程及封装成类的操作
2020/05/12 Python
解决pymysql cursor.fetchall() 获取不到数据的问题
2020/05/15 Python
python3代码中实现加法重载的实例
2020/12/03 Python
金牌葡萄酒俱乐部:Gold Medal Wine Club
2017/11/02 全球购物
澳大利亚墨尔本的在线时装店:LORETA
2018/09/14 全球购物
如何写你的创业计划书
2014/01/07 职场文书
十岁生日同学答谢词
2014/01/19 职场文书
财务年终工作总结大全
2019/06/20 职场文书
《没有任何借口》读后感:完美的执行能力
2020/01/07 职场文书