前端框架路由實現的Hash和History兩種模式的區別
前言
- 以前面試的時候就有準備過前端框架中兩種路由實現方式及區別,可是當時沒專門下功夫去深刻了解,就在網上搜了下別人總結的臨時抱了下佛腳。可是事實證實,出來混,老是要還的,在後來的面試中又遇到了,並且此次問得更加深刻,僅僅靠死記硬背來的知識老是遺忘得很快,網上別人總結的東西終歸仍是別人的,鑑於網上別人總結的內容有點雜亂無章,仍是決定本身在此總結記錄一番,以加深印象。
1、何爲前端路由
- 路由的概念來自於服務器端,在SPA(單頁應用)中,路由描述的是URL到函數的映射關係,即在瀏覽器中輸入一個URL,相應的控制器會對提交的請求進行解析,而後進行路由匹配,找到對應的模塊和函數進行執行。
2、如何實現
- 實現的兩個核心問題是如何檢測路由變化和如何改變URL而不刷新頁面,一般有兩種實現模式,一種是Hash模式,一種是History模式。
3、Hash模式
- 早期的前端路由的實現就是基於
location.hash
來實現的,location.hash
的值就是URL中#後面的內容 其實現原理就是監聽#後面的內容來發起Ajax請求來進行局部更新,而不須要刷新整個頁面。
- 使用
hashchange
事件來監聽 URL 的變化,如下這幾種狀況改變 URL 都會觸發 hashchange
事件:瀏覽器前進後退改變 URL、<a>
標籤改變 URL、window.location改變URL。
優缺點
- 兼容低版本瀏覽器,Angular1.x和Vue默認使用的就是hash路由
- 只有#符號以前的內容纔會包含在請求中被髮送到後端,也就是說就算後端沒有對路由全覆蓋,可是不會返回404錯誤
- hash值的改變,都會在瀏覽器的訪問歷史中增長一個記錄,因此能夠經過瀏覽器的回退、前進按鈕控制hash的切換
- 會覆蓋錨點定位元素的功能
- 不太美觀,#後面傳輸的數據複雜的話會出現問題
4、History模式
- history 提供了
pushState
和 replaceState
兩個方法來記錄路由狀態,這兩個方法改變 URL 不會引發頁面刷新
- history 提供相似 hashchange 事件的 popstate 事件,但 popstate 事件有些不一樣:經過瀏覽器前進後退改變 URL 時會觸發 popstate 事件,經過pushState/replaceState或
<a>
標籤改變 URL 不會觸發 popstate 事件。好在咱們能夠攔截 pushState/replaceState的調用和<a>
標籤的點擊事件來檢測 URL 變化,因此監聽 URL 變化能夠實現,只是沒有 hashchange 那麼方便。
pushState(state, title, url)
和 replaceState(state, title, url)
均可以接受三個相同的參數:
- state:須要保存的數據,這個數據在觸發popstate事件時,能夠在event.state裏獲取
- title:標題,基本沒用,通常傳 null
- url:設定新的歷史記錄的 url,新的 url 與當前 url 的 origin 必須是同樣的,不然會拋錯,url能夠是絕對路徑,也能夠是相對路徑。
優缺點
- 使用簡單,比較美觀
pushState()
設置新的URL能夠是任意與當前URL同源的URL,而hash只能改變#後面的內容,所以只能設置與當前URL同文檔的URL
pushState()
設置的URL與當前URL如出一轍時也會被添加到歷史記錄棧中,而hash#後面的內容必須被修改纔會被添加到新的記錄棧中
pushState()
能夠經過stateObject
參數添加任意類型的數據到記錄中,而hash只能添加短字符串
pushState()
可額外設置title屬性供後續使用
- 前端的URL必須和向發送請求後端URL保持一致,不然會報404錯誤
- 因爲History API的緣故,低版本瀏覽器有兼容行問題
參考
歡迎關注本站公眾號,獲取更多信息