一文了解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 相关文章推荐
Dom 是什么的详细说明
Oct 25 Javascript
33个优秀的 jQuery 图片展示插件分享
Mar 14 Javascript
jquery队列queue与原生模仿其实现方法分享
Mar 25 Javascript
jquery实现下拉菜单的二级联动利用json对象从DB取值显示联动
Mar 27 Javascript
Javascript中设置默认参数值示例
Sep 11 Javascript
js仿腾讯QQ的web登陆界面
Aug 19 Javascript
jquery事件绑定解绑机制源码解析
Sep 19 Javascript
vuejs绑定class和style样式
Apr 11 Javascript
基于代数方程库Algebra.js解二元一次方程功能示例
Jun 09 Javascript
Angular5.1新功能分享
Dec 21 Javascript
ES6的Fetch异步请求的实现方法
Dec 07 Javascript
在Create React App中启用Sass和Less的方法示例
Jan 16 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与SQL注入攻击[三]
2007/04/17 PHP
PHP explode()函数用法、切分字符串
2012/10/03 PHP
CodeIgniter模板引擎使用实例
2014/07/15 PHP
PHP中unset,array_splice删除数组中元素的区别
2014/07/28 PHP
php简单判断两个字符串是否相等的方法
2015/07/13 PHP
php获取远程图片并下载保存到本地的方法分析
2016/10/08 PHP
php微信开发之谷歌测距
2018/06/14 PHP
js静态作用域的功能。
2006/12/25 Javascript
Prototype使用指南之base.js
2007/01/10 Javascript
Bootstrap每天必学之基础排版
2015/11/20 Javascript
基于Bootstrap3表格插件和分页插件实例详解
2016/05/17 Javascript
jQuery实现radio第一次点击选中第二次点击取消功能
2017/05/15 jQuery
深入理解Commonjs规范及Node模块实现
2017/05/17 Javascript
vue init webpack myproject构建项目 ip不能访问的解决方法
2018/03/20 Javascript
vue-cli配置环境变量的方法
2018/07/09 Javascript
vue-router的HTML5 History 模式设置
2018/09/08 Javascript
React 使用recharts实现散点地图的示例代码
2018/12/07 Javascript
微信小程序image图片加载完成监听
2019/08/31 Javascript
JavaScript中如何对多维数组(矩阵)去重的实现
2019/12/04 Javascript
vue 实现用户登录方式的切换功能
2020/04/14 Javascript
js动态生成表格(节点操作)
2021/01/12 Javascript
Python字符编码判断方法分析
2016/07/01 Python
在OpenCV里实现条码区域识别的方法示例
2019/12/04 Python
Python调用.net动态库实现过程解析
2020/06/05 Python
CSS3制作酷炫的条纹背景
2017/11/09 HTML / CSS
GafasWorld西班牙:购买太阳镜、眼镜和隐形眼镜
2019/09/08 全球购物
校本教研工作制度
2014/01/22 职场文书
小学教师师德演讲稿
2014/05/06 职场文书
五水共治一句话承诺
2014/05/30 职场文书
预防传染病方案
2014/06/14 职场文书
向国旗敬礼活动总结
2014/09/27 职场文书
幼儿园综治宣传月活动总结
2015/05/07 职场文书
刑事附带民事上诉状
2015/05/23 职场文书
微信早安问候语
2015/11/10 职场文书
Spring Boot配合PageHelper优化大表查询数据分页
2022/04/20 Java/Android