React 學習之路由HashRouter和BrowserRouter


React路由有兩種實現方式:

  • HashRouter:利用hash實現路由切換
  • BrowserRouter:利用h5 Api實現路由切換

1.1 HashRouter

利用hash實現路由切換

<body>
    <div id="root"></div>
    <a href="#/a">去/a</a>
    <a href="#/b">去/b</a>
  </body>
  <script> let root = document.getElementById('root') window.addEventListener('hashchange',(event) =>{ let hash = window.location.hash root.innerHTML = hash }) </script>

模擬點擊切換頁面,每當瀏覽器里的hash值發生變化之后,就會觸發一個事件,叫hashchange,這個函數有一個回調,可以通過window.location.hash拿到當前的hash值。

 

 

 1.2 BrowserRouter (瀏覽器路由)

利用h5 Api實現路由切換,主要是借助history對象。

  • history對象提供了操作瀏覽器會話的歷史接口。
  • historylength屬性聲明了瀏覽器歷史列表中的元素數量。
  • pushState,H5引入了history.pushState()和history.replaceState()方法,它們分別可以添加和修改歷史記錄的條目,這些方法通常與window.onpopstate配合使用
  • onpopstate,window.onpopstate是popstate事件再window對象上的事件處理程序
 setTimeout( () => { //pushState不會觸發事件
      window.history.pushState({page: 1},'page1','/page1') },1000) setTimeout( () => { //pushState不會觸發事件
      window.history.pushState({page: 2},'page2','/page2') },2000) setTimeout( () => { //pushState不會觸發事件
      window.history.pushState({page: 3},'page3','/page3') },3000) //后退的時候觸發popstate
    setTimeout( () => { //go(-1)后退一個,會觸發popstate事件
      window.history.go(-1) },4000)

通過 window.history.pushState可以向history容器中存入當前路徑,這個容器結構類似於棧,后進先出,當然也可以通過window.history.go這個方法后退到前一個路徑,這個方法會觸發一個popstate事件,通過這個事件我們可以做一些操作,比如向頁面添加內容等:

//這個事件會在go(-1)的時候觸發,可以在觸發的時候改變文檔內容
    window.onpopstate = function(event){ console.log(event) root.innerHTML = window.location.pathname }

 

 history對象在回退的時候有事件,但是在pushstate的時候並不會觸發事件,我們要想自己做一些操作就需要改寫一個onpushState事件,以便我們進行頁面操作。

let root = document.getElementById('root') window.onpushstate = function(state,title,url) { root.innerHTML = url } ;(function (history) { //1.緩存原生的pushState方法
      let pushState = history.pushState //2.改寫pushState方法
      history.pushState = function(state,title,url) { //3.自定義改寫后的事件名為onpushstate
        if(typeof window.onpushstate === 'function') { window.onpushstate(state,title,url) } //4.調用原生方法並且執行
 pushState.call(history,state,title,url) } })(window.history)

看過vue源碼的同學肯定知道vue里面對數組的響應式處理就是通過改寫數組的那7個方法實現的。我們這里也一樣,攔截了原生的方法,對原生方法進行了緩存,然后再改寫原生方法,最后再執行,就這么簡單。

完整版:

<body>
    <div id="root"></div>
  </body>
  <script> let root = document.getElementById('root') window.onpushstate = function(state,title,url) { root.innerHTML = url } ;(function (history) { //1.緩存原生的pushState方法
      let pushState = history.pushState //2.改寫pushState方法
      history.pushState = function(state,title,url) { //3.自定義改寫后的事件名為onpushstate
        if(typeof window.onpushstate === 'function') { window.onpushstate(state,title,url) } //4.調用原生方法並且執行
 pushState.call(history,state,title,url) } })(window.history) //這個事件會在go(-1)的時候觸發,可以在觸發的時候改變文檔內容
    window.onpopstate = function(event){ console.log(event) root.innerHTML = window.location.pathname } // window.history 這是瀏覽器原生提供的對象,通過它來操作會話容器
    setTimeout( () => { //pushState不會觸發事件
      window.history.pushState({page: 1},'page1','/page1') },1000) setTimeout( () => { //pushState不會觸發事件
      window.history.pushState({page: 2},'page2','/page2') },2000) setTimeout( () => { //pushState不會觸發事件
      window.history.pushState({page: 3},'page3','/page3') },3000) //后退的時候觸發popstate
    setTimeout( () => { //go(-1)后退一個,會觸發popstate事件
      window.history.go(-1) },4000) </script>

下一節寫一個自己的路由庫!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM