HashHistory

class HashHistory extends History{
  constructor(router,base,fallback){
    super(router,base)
    if(fallback && checkFallBack(this.base)){
      return
    }
    // Initializes the route switchover
    ensureSlash()
  }
  setupListeners(){
    if(this.listeners.length > 0) {return
    }
    const router = this.router
    const expectScroll = router.options.scrollBehavior
    const supportsScroll = supportsPushState && expectScroll
    // Determine the added scrolling Settings and support scrolling behavior, add page switch record scrolling position
    if(supportsScroll){
      this.listeners.push(setupScroll())
    }
    const handleRoutingEvent = () = > {
      const current = this.current
      // Check that the current hash address is changed and return directly
      if(! ensureSlash()){return
      }
      // Otherwise, switch the route
      this.transitionTo(getHash(),route= > {
        // The page scrolls after switching
        if(supportsScroll){
          handleScroll(this.router,route,current,true)}// If pushState/ hash is not supported
        if(! supportsPushState){ replaceHash(route.fullPath) } }) }// Check whether pushState is supported. Path changes listen for popState time or hash events
      const eventType = supportsPushState ? 'popstate' : 'hashchange'
      // Path change, handleRoutingEvent
      window.addEventListener(eventType,handleRoutingEvent)
      this.listeners.push(() = > {
        window.removeEventListener(eventType,handleRoutingEvent)
      })
  }
  push(location,onComplete,onAbort){
    const { current: fromRoute} = this
    // Switch routes/route guard events/page scrolling
    this.transitionTo(location,route= > {
      pushHash(route.fullPath)
      handleScroll(this.router,route,fromRoute,false)
      onComplete && onComplete(route)
    },onAbort)
  }
  replace(location,onComplete,onAbort){
    const { current: fromRoute } = this
    // Perform route guard/switch routes/page scroll
    this.transitionTo(location,route= > {
      replaceHash(route.fullPath)
      handleScroll(this.router,route,fromRoute,false)
      onComplete && onComplete(route)
    },onAbort)
  }
  go(n){
    window.history.go(n)
  }
  ensureURL(push){
    // Check whether the path and route object are the same. If they are not, jump again
    const current = this.current.fullPath
    if(getHash() ! == current) push ? pushHahs(current) : replaceHash(current) }getCurrentLocation(){
    // Get the current path
    return getHash()
  }
}
Copy the code

checkFallBack

function checkFallBack(base){
  // Get the base based path
  const location = getLocation(base)
  // Determine a path that does not start with /#
  if(!/ # ^ / / /.test(location)){
    // Replace the current location with /base/#/ path
    window.location.replace(cleanPath(base + '/ #' + location))
    return true}}Copy the code

ensureSlash

function ensureSlash(){
  // Get the hash value of the current path
  const path = getHash()
  if(path.charAt(0) = = ='/') {return true
  }
  replaceHash('/'+hash)
  return false
}
Copy the code
getHash
function getHash(){
  / / get the hash
  let href = window.location.href
  const index = href.indexOf(The '#')
  if(index < 0) return ' '
  href = href.slice(index + 1)
  return href
}
Copy the code
replaceHash
function replaceHash(path){
  // Route switchover
  if(supportsPushState){
    replaceState(path)
  }else{
    window.location.replace(getUrl(path))
  }
}
Copy the code
getUrl
function getUrl(path){
  // Generates the hash address for the current path
  const href = window.location.href
  const i = href.indexOf(The '#')
  const base = i >= 0 ? href.slice(0,i) : href
  return `${base}#${path}`
}
Copy the code

pushHash

function pushHash(path){
  // Switch paths
  if(supportsPushState){
    pushState(getUrl(path))
  }else{
    window.location.hash = hash
  }
}
Copy the code