1. 程式人生 > >手摸手教你自己動手實現一個前端路由

手摸手教你自己動手實現一個前端路由

前言

用過現代前端框架的同學,對前端路由一定不陌生, vue, react, angular 都有自己的 router, 那麼你對 router 的工作原理了解嗎?

如果還不瞭解, 那麼請跟我一起來手寫一個簡單的前端路由, 順便了解一下.

實現路由的2種方式

  1. hash模式
  2. history模式

缺點:

hash:醜(位址列要多一個#), 某些特殊場景有坑 ,如微信支付回撥

history: 相容性較差, 直接訪問會400 ,除非後端或者伺服器有做處理

基本原理

hash是基於 監聽 hashchange 事件實現的,history 是基於 pushState 和 popState,

實現

由於history相容性較差,而且實現方式基本沒多大區別,本文就以hash模式來實現,history的實現方式只實現不同的部分。

手摸手教你自己動手實現一個前端路由

 

以上就是hash模式的最簡單實現,檢視控制檯,可以看到不管是點選跳轉按鈕,還是點選瀏覽器的前進/後退按鈕,控制檯都會輸出當前頁面對應的 'url',有了 'url',我們就可以對內容做條件渲染了

我們在上面的程式碼的基礎上,稍作修改一下,增加2個div,一個是login,一個是index

手摸手教你自己動手實現一個前端路由

 

這樣,我們就能根據不同的hash地址,顯示不同的內容,是不是已經有點路由的味道了呢?但是目前還無法傳參,傳參的方式有很多種,最常見最通俗的,應該是query string 了吧? query string 其實很簡單,解析url即可。

手摸手教你自己動手實現一個前端路由

 

這樣,我們就能獲取到URL上傳遞的query string , 還順便解決了傳參會導致路由解析不正確的bug.

傳參其實還有個更簡單的方法,就是 設定一個全域性變數 param,然後在需要傳值的時候,直接對param 賦值即可

手摸手教你自己動手實現一個前端路由

 

由於是全域性變數,所以可以在任意位置使用 param,不過這樣直接使用全域性變數的方式,也有它的弱點,就是點選返回按鈕的時候無法儲存變數,而query string 因為是在 url 裡面的,所以返回的時候,可以拿到上個頁面的 query string,

那我們有沒有辦法讓全域性變數的方式也能儲存上一個頁面的引數呢? 我們來稍微修改一下程式碼

手摸手教你自己動手實現一個前端路由

 

那我們在 hashchange 的時候,可以根據url來定位該頁面的引數。nainaitea.com

手摸手教你自己動手實現一個前端路由

 

這樣,我們就初步實現了一個hash路由,那麼接下來,我們來看看history路由怎麼實現。

history 模式

history 模式主要依靠 呼叫 history.pushState() 方法 和 監聽 popstate 事件。

history.pushState() 方法接收3個引數:

  1. 要傳遞的資料(引數)
  2. 給頁面設定的標題(相容性差,幾乎沒用)
  3. url

我們看看呼叫例項

手摸手教你自己動手實現一個前端路由

 

需要注意的是 pushState 的時候,並不會觸發 popstate 事件,只有在前進後退的時候,才會觸發,所以 pushState 之後,需要手動去設定頁面的相關狀態。如上面的例子,我們需要這樣做

手摸手教你自己動手實現一個前端路由

 

然後監聽 popstate 事件,捕獲 前進/後退

手摸手教你自己動手實現一個前端路由

 

最後

本文最終實現程式碼已經放在 github上,想要直接看效果的同學,可以上去直接copy,執行。

如果覺得本文對您有用,請給本文的github加個star,萬分感謝

另外,github上還有其他一些關於前端的教程和元件,有興趣的童鞋可以看看,你們的支援就是我最大的動力。