一文了解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 相关文章推荐
jquery实现网站超链接和图片提示效果
Mar 21 Javascript
js 定时器setTimeout无法调用局部变量的解决办法
Nov 28 Javascript
avalonjs制作响应式瀑布流特效
May 06 Javascript
js实现简单的省市县三级联动效果实例
Feb 18 Javascript
简单总结JavaScript中的String字符串类型
May 26 Javascript
功能强大的jquery.validate表单验证插件
Nov 07 Javascript
详解jQuery简单的表格应用
Dec 16 Javascript
Vue.js 2.0中select级联下拉框实例
Mar 06 Javascript
jQuery插件FusionCharts绘制的3D环饼图效果示例【附demo源码】
Apr 02 jQuery
在vue项目中引用Iview的方法
Sep 14 Javascript
D3.js(v3)+react 实现带坐标与比例尺的柱形图 (V3版本)
May 09 Javascript
微信小程序文字显示换行问题
Jul 28 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
Google Voice 短信发送接口PHP开源版(2010.5更新)
2010/07/22 PHP
php 生成自动创建文件夹并上传文件的示例代码
2014/03/07 PHP
微信公众平台天气预报功能开发
2014/07/06 PHP
php实现微信支付之现金红包
2018/05/30 PHP
浅谈PHP SHA1withRSA加密生成签名及验签
2019/03/18 PHP
用 Javascript 验证表单(form)中的单选(radio)值
2009/09/08 Javascript
ext 列表页面关于多行查询的办法
2010/03/25 Javascript
JS继承--原型链继承和类式继承
2013/04/08 Javascript
常见表单重复提交问题整理及解决方法
2013/11/13 Javascript
.NET微信公众号开发之创建自定义菜单
2015/07/16 Javascript
关于JS中setTimeout()无法调用带参函数问题的解决方法
2016/06/21 Javascript
js 点击a标签 获取a的自定义属性方法
2016/11/21 Javascript
Bootstrap table简单使用总结
2017/02/15 Javascript
js 数字、字符串、布尔值的转换方法(必看)
2017/04/07 Javascript
Easyui Datagrid自定义按钮列(最后面的操作列)
2017/07/13 Javascript
canvas基础绘制-绚丽倒计时的实例
2017/09/17 Javascript
利用express启动一个server服务的方法
2017/09/17 Javascript
Node.js npm命令运行node.js脚本的方法
2018/10/10 Javascript
vue实现随机验证码功能的实例代码
2019/04/30 Javascript
Javascript摸拟自由落体与上抛运动原理与实现方法详解
2020/04/08 Javascript
详解微信小程序轨迹回放实现及遇到的坑
2021/02/02 Javascript
Python验证码识别的方法
2015/07/10 Python
Python基于更相减损术实现求解最大公约数的方法
2018/04/04 Python
python线程池threadpool使用篇
2018/04/27 Python
Python 删除整个文本中的空格,并实现按行显示
2018/07/24 Python
python3 xpath和requests应用详解
2020/03/06 Python
Pytorch mask-rcnn 实现细节分享
2020/06/24 Python
Python使用pickle进行序列化和反序列化的示例代码
2020/09/22 Python
师范生自我鉴定范文
2013/10/05 职场文书
岗位职责的构建方法
2014/02/01 职场文书
总经理助理职责
2014/02/04 职场文书
对公司合理化的建议书
2014/03/12 职场文书
机械机修工岗位职责
2014/08/03 职场文书
保护地球的宣传语
2015/07/13 职场文书
爱心捐赠活动简讯
2015/07/20 职场文书
《海上日出》教学反思
2016/02/23 职场文书