搞懂前端路由的两种模式

121 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情

前言

从事前端,都会遇到路由,而在很久以前路由都是由后端来控制的,但是现在很流行spa页面开发,所以路由控制权交给了前端,那么前端的路由的实现方式有哪些呢?

  • hash模式
  • history模式

实现方式

hash模式

主要是监听到路由hash的变化使用js去控制页面的展示。

那什么是hash?

hash是 网页地址中以#结尾(包含#)的字符串,例如:http://domin:port/index.html#list ,#list就是hash

怎么监听路由的变化?

浏览器给我们提供了一个API叫做 hashchange,当我们改变hash值时,就会触发这个事件,我们再用js去控制内容的展示和隐藏,这样我们就实现了前端的路由。

案例:

<body>
    <a href="#a"> 跳转到a页面 </a>
    <a href="#b">跳转到b页面 </a>
</body>
   <script>

      window.addEventListener('hashchange',e=>{
         console.log(e)
      })
   </script>

现在我们页面上有两个按钮,我们点击a按钮时导致浏览器的地址的hash发生变化,于是便触发了hashchange事件,看看打印了什么。 里面有newUrl,oldUrl等信息,正是我们需要的。

history模式

history模式HTML5给我们提供了一个History对象,包含了用户在浏览器里面访问过的url.

就刚才那个例子,我们在控制台里面执行window.history,看看打印了什么吧。

history对象给我提供了一些属性和方法:

  • length:表示当前浏览器记录了当前网页的数量
  • back():加载历史会话的前一个url,和浏览器回退功能一致
  • forward():加载历史会话的下一个url,和浏览器的前进功能一致
  • go():加载到历史会话中的某一个具体的url
  • pushState():将当前网页地址压进历史会话中
  • replaceState():将当前网页地址替换成其它地址

history模式主要就是依赖于pushStatereplaceState这两个api

pushState

pushState只是修改history对象,并不会导致页面的刷新。并且不会触发hashchange事件。

history.pushState(state, title[, url])

  • state:状态对象是一个 JavaScript 对象,它与pushState()创建的新历史记录条目相关联。 每当用户导航到新状态时,都会触发popstate事件,并且该事件的状态属性包含历史记录条目的状态对象的副本。
  • title:标题,可以传入空字符串
  • url:可选的

再刚才那个例子里面加点料:

<body>
    <a href="#a"> 跳转到a页面 </a>
    <a href="#b">跳转到b页面 </a>
</body>
<script>
    window.addEventListener('hashchange', e => {
        console.log(e)
    })

    window.history.pushState({
        id: 1
    }, "", "")

</script>

打开控制台,看见并没有触发hashchange事件,执行window.history看见window.history.state有值了:

replaceState

history.replaceState(stateObj, title[, url]);

  • stateObj :状态对象是一个 JavaScript 对象,它与传递给 replaceState 方法的历史记录实体相关联
  • title:标题,可以传入空字符串
  • url:可选的

还是刚才的例子改写一下:

<body>
    <a href="#a"> 跳转到a页面 </a>
    <a href="#b">跳转到b页面 </a>
    <button onclick="tz()">跳转到</button>
</body>
<script>
    window.addEventListener('hashchange', e => {
        console.log(e)
    })

    window.history.pushState({
        id: 1
    }, "", "c.html")
    const tz = () => {
        window.history.replaceState({
            id: 2
        }, "", "b.html")
    }

</script>

当前页面的名字为index.html,现在我们点击按钮,url会变成http://127.0.0.1:5500/vueRouter/b.html,但是页面并没有发生变化。是有浏览器回退功能,地址会重新变为index.html的,会跳过c.html这个页面。

end

每天进步一点点。