一文了解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属性过滤选择器使用示例
Jun 18 Javascript
JS操作CSS随机改变网页背景实现思路
Mar 10 Javascript
js数组操作方法总结(必看篇)
Nov 22 Javascript
JS限制条件补全问题实例分析
Dec 16 Javascript
JS简单判断滚动条的滚动方向实现方法
Apr 28 Javascript
js仿微信抢红包功能
Sep 25 Javascript
webpack 样式加载的实现原理
Jun 12 Javascript
Vue.js项目实战之多语种网站的功能实现(租车)
Aug 07 Javascript
基于vue-draggable 实现三级拖动排序效果
Jan 10 Javascript
Javascript作用域和作用域链原理解析
Mar 03 Javascript
文章或博客自动生成章节目录索引(支持三级)的实现代码
May 10 Javascript
JS 逻辑判断不要只知道用 if-else 和 switch条件判断(小技巧)
May 27 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数组函数序列之array_unshift() 在数组开头插入一个或多个元素
2011/11/07 PHP
php数组编码转换示例详解
2014/03/11 PHP
php打印输出棋盘的实现方法
2014/12/23 PHP
PHP实现的策略模式简单示例
2017/08/25 PHP
JavaScript 语言的递归编程
2010/05/18 Javascript
Dreamweaver jQuery智能提示插件,支持版本提示,支持1.6api
2011/07/31 Javascript
同时使用n个window onload加载实例介绍
2013/04/25 Javascript
jQuery自定义添加&quot;$&quot;与解决&quot;$&quot;冲突的方法
2015/01/19 Javascript
window.open()实现post传递参数
2015/03/12 Javascript
JQuery select(下拉框)操作方法汇总
2015/04/15 Javascript
js获取html的span标签的值方法(超简单)
2016/07/26 Javascript
JS控件bootstrap datepicker使用方法详解
2017/03/25 Javascript
JS数组操作之增删改查的简单实现
2017/08/21 Javascript
Vuejs在v-for中,利用index来对第一项添加class的方法
2018/03/03 Javascript
用Electron写个带界面的nodejs爬虫的实现方法
2019/01/29 NodeJs
Vue keepAlive 数据缓存工具实现返回上一个页面浏览的位置
2019/05/10 Javascript
[05:08]第一届“网鱼杯”DOTA2比赛精彩集锦
2014/09/05 DOTA
用Python写冒泡排序代码
2016/04/12 Python
详解python函数传参是传值还是传引用
2018/01/16 Python
python将字典内容存入mysql实例代码
2018/01/18 Python
Python 实现删除某路径下文件及文件夹的实例讲解
2018/04/24 Python
法国奢华女性时尚配饰网上商店:Monnier Frères
2016/08/27 全球购物
Lacoste澳大利亚官网:服装、鞋类及配饰
2018/11/14 全球购物
使用useBean标志初始化BEAN时如何接受初始化参数
2012/02/11 面试题
北京RT科技有限公司.net工程师面试题
2013/02/15 面试题
生物学学生自我评价
2014/01/17 职场文书
本科毕业生专业自荐书范文
2014/02/05 职场文书
考察现实表现材料
2014/05/19 职场文书
幽默自我介绍演讲稿
2014/08/21 职场文书
购房协议书范本
2014/10/02 职场文书
车队安全员岗位职责
2015/02/15 职场文书
2015年政治教研组工作总结
2015/07/22 职场文书
导游词之四川熊猫基地
2020/01/13 职场文书
Shell脚本一键安装Nginx服务自定义Nginx版本
2022/03/20 Servers
i5-10400f处理相当于i7多少水平
2022/04/19 数码科技
MySQL索引失效场景及解决方案
2022/07/23 MySQL