欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-10-15 18:38:18
当前版本: 3.0.3 类目录: src/history/base.js hash模式 即地址栏 url 中的 # 符号(此 hash 不是密码学里的散列运算)。比如...

当前版本: 3.0.3

类目录: src/history/base.js

hash模式

即地址栏 url 中的 # 符号(此 hash 不是密码学里的散列运算)。比如这个 url: ,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模式,希望对大家有所帮助