路由 hash history详解

905 阅读1分钟

前端路由分为两种,一种是hash路由,形式为/#/a/b/c, 一种是hostory路由,形式为/a/b/c,各自都有浏览器支持的api,下面一起详细的看看他们各自的知识

hash路由

hash的变化不会引起浏览器的刷新,可以通过localtion.hash来查看当前页面的hash,也可以通过localtion.hash = a 来改变当前页面的hash。
可以通过window.addEventListener('hashchange',() =>{ })来监听页面hash的变化

hash路由实战

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style></style>
  </head>
  <body>
    <ul>
      <li><a href="#/">我是主页</a></li>
      <li><a href="#/a">我是a页面</a></li>
      <li><a href="#/b">我是b页面</a></li>
    </ul>
    <script>
      class HashRouter{
          constructor(){
           this.routes = {}
           this.currentHash = ''
           const hashChangeUrl = this.hashChangeUrl.bind(this)
           window.addEventListener('load', hashChangeUrl, false)
           window.addEventListener('hashchange', hashChangeUrl, false)
         }
         route(path, callback){
           this.routes[path] = callback || function(){}
         }
         hashChangeUrl(){
           console.log('hashChangeUrl')
           this.currentHash = location.hash.slice(1) || '/'
           this.routes[this.currentHash] && this.routes[this.currentHash]()
         }
       }
       const Router = new HashRouter()
       const body = document.querySelector('body')
       const changeColor = function(color){
         body.style.backgroundColor = color
       }
       Router.route('/', () => {
         changeColor('red')
       })
       Router.route('/a', () => {
         changeColor('green')
       })
       Router.route('/b', () => {
         changeColor('#cddc39')
       })
     </script>
  </body>
</html>

history路由

history路由的变化配上a标签的时候会引起页面的刷新
history.push()方法会向history栈中添加一个history并改变当前页面的history值 history.replace()方法会当前页面的history值,并在history栈中删除原来的history值
history.back()方法可以改变页面的history值至上一个值
history.go()方法可以向前或者前后改变history的值 popstate事件可以监听除push方法以外的方式引起的history的变化

history路由实战

    <!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style></style>
  </head>
  <body>
    <ul>
      <li><a href="/">我是主页</a></li>
      <li><a href="/a">我是a页面</a></li>
      <li><a href="/b">我是b页面</a></li>
    </ul>
    <script>
    class HistoryRoutes{
      constructor(){
        this.routes = []
        window.addEventListener('popstate', (e) => {
          console.log('popstate')
          const path = this.getState()
          this.routes[path] && this.routes[path]()
        })
      }
      getState(){
        const path = window.location.pathname
        return path ? path : '/'
      }
      route(path, callback){
        this.routes[path] = callback || function(){}
      }
      go(path){
        history.pushState(null, null, path)
        this.routes[path]()
      }
    }
    const Router = new HistoryRoutes()
    const body = document.querySelector('body')
    const changeColor = function(color){
      body.style.backgroundColor = color
    }
    Router.route('/', () => {
      changeColor('red')
    })
    Router.route('/a', () => {
      changeColor('green')
    })
    Router.route('/b', () => {
      changeColor('#cddc39')
    })
    const ul = document.querySelector('ul')
    ul.addEventListener('click', (e) => {
      if(e.target.tagName === 'A'){
        e.preventDefault()
        Router.go(e.target.getAttribute('href'))
      }
    })
    </script>
  </body>
</html>