前言
- 之前面試的時候就有準備過前端框架中兩種路由實現(xiàn)方式及區(qū)別糊渊,但是當時沒專門下功夫去深入了解麸粮,就在網(wǎng)上搜了下別人總結(jié)的臨時抱了下佛腳。但是事實證明酬滤,出來混签餐,總是要還的,在后來的面試中又遇到了盯串,而且這次問得更加深入氯檐,僅僅靠死記硬背來的知識總是遺忘得很快,網(wǎng)上別人總結(jié)的東西終歸還是別人的体捏,鑒于網(wǎng)上別人總結(jié)的內(nèi)容有點雜亂無章冠摄,還是決定自己在此總結(jié)記錄一番,以加深印象几缭。
一河泳、何為前端路由
- 路由的概念來自于服務(wù)器端,在SPA(單頁應(yīng)用)中奏司,路由描述的是URL到函數(shù)的映射關(guān)系乔询,即在瀏覽器中輸入一個URL,相應(yīng)的控制器會對提交的請求進行解析韵洋,然后進行路由匹配竿刁,找到對應(yīng)的模塊和函數(shù)進行執(zhí)行。
二搪缨、如何實現(xiàn)
- 實現(xiàn)的兩個核心問題是如何檢測路由變化和如何改變URL而不刷新頁面食拜,通常有兩種實現(xiàn)模式,一種是Hash模式副编,一種是History模式负甸。
三、Hash模式
- 早期的前端路由的實現(xiàn)就是基于
location.hash
來實現(xiàn)的,location.hash
的值就是URL中#后面的內(nèi)容
其實現(xiàn)原理就是監(jiān)聽#后面的內(nèi)容來發(fā)起Ajax請求來進行局部更新呻待,而不需要刷新整個頁面打月。 - 使用
hashchange
事件來監(jiān)聽 URL 的變化,以下這幾種情況改變 URL 都會觸發(fā)hashchange
事件:瀏覽器前進后退改變 URL蚕捉、<a>標簽改變 URL奏篙、window.location改變URL。
優(yōu)缺點
- 兼容低版本瀏覽器迫淹,Angular1.x和Vue默認使用的就是hash路由
- 只有#符號之前的內(nèi)容才會包含在請求中被發(fā)送到后端秘通,也就是說就算后端沒有對路由全覆蓋,但是不會返回404錯誤
- hash值的改變敛熬,都會在瀏覽器的訪問歷史中增加一個記錄肺稀,所以可以通過瀏覽器的回退、前進按鈕控制hash的切換
- 會覆蓋錨點定位元素的功能
- 不太美觀应民,#后面?zhèn)鬏數(shù)臄?shù)據(jù)復(fù)雜的話會出現(xiàn)問題
四话原、History模式
- history 提供了
pushState
和replaceState
兩個方法來記錄路由狀態(tài),這兩個方法改變 URL 不會引起頁面刷新 - history 提供類似 hashchange 事件的 popstate 事件瑞妇,但 popstate 事件有些不同:通過瀏覽器前進后退改變 URL 時會觸發(fā) popstate 事件稿静,通過pushState/replaceState或<a>標簽改變 URL 不會觸發(fā) popstate 事件。好在我們可以攔截 pushState/replaceState的調(diào)用和<a>標簽的點擊事件來檢測 URL 變化辕狰,所以監(jiān)聽 URL 變化可以實現(xiàn)改备,只是沒有 hashchange 那么方便。
-
pushState(state, title, url)
和replaceState(state, title, url)
都可以接受三個相同的參數(shù): - state:需要保存的數(shù)據(jù)蔓倍,這個數(shù)據(jù)在觸發(fā)popstate事件時悬钳,可以在event.state里獲取
- title:標題,基本沒用偶翅,一般傳 null
- url:設(shè)定新的歷史記錄的 url默勾,新的 url 與當前 url 的 origin 必須是一樣的,否則會拋錯聚谁,url可以是絕對路徑母剥,也可以是相對路徑。
優(yōu)缺點
- 使用簡單形导,比較美觀
-
pushState()
設(shè)置新的URL可以是任意與當前URL同源的URL环疼,而hash只能改變#后面的內(nèi)容,因此只能設(shè)置與當前URL同文檔的URL -
pushState()
設(shè)置的URL與當前URL一模一樣時也會被添加到歷史記錄棧中朵耕,而hash#后面的內(nèi)容必須被修改才會被添加到新的記錄棧中 -
pushState()
可以通過stateObject
參數(shù)添加任意類型的數(shù)據(jù)到記錄中炫隶,而hash只能添加短字符串 -
pushState()
可額外設(shè)置title屬性供后續(xù)使用 - 前端的URL必須和向發(fā)送請求后端URL保持一致,否則會報404錯誤
- 由于History API的緣故阎曹,低版本瀏覽器有兼容行問題