首页 > 编程 > JavaScript > 正文

一文了解vue-router之hash模式和history模式

2019-11-19 11:25:16
字体:
来源:转载
供稿:网友

当前版本: 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模式,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表