淺談前端路由

關(guān)于秋招的一些感想

最近一段時間忙著秋招烈疚,一路經(jīng)歷了阿里終面掛,美團(tuán)終面掛等等聪轿,感覺自己有點苦逼(尤其是因為沒HC而掛是最難受的)爷肝。雖然到現(xiàn)在還沒得到滿意的結(jié)果,但這個過程還是有所收獲的陆错,這是雖然一個自我懷疑的過程灯抛,但也是一個不斷彌補自身不足,學(xué)習(xí)的過程音瓷,其中與一些面試我的師兄在交流的過程中也是受益匪淺对嚼,并且也對自身以后要走的路有了一個更加明確的認(rèn)識,所以前途漫漫還需努力呀外莲!

一猪半、路由

在現(xiàn)代前端開發(fā)中兔朦,路由是非常重要的一環(huán)偷线。但路由到底是什么呢?有些說:路由就是指隨著瀏覽器地址欄的變化沽甥,展示給用戶的頁面也不相同声邦。這是從路由的用途上來解釋路由是什么的,還有一種說法是:路由就是URL到函數(shù)的映射摆舟。這是從路由的實現(xiàn)原理上來解釋路由是什么的亥曹。這兩種說法都很有道理,但我個人認(rèn)為還是第二種比較切合我自己對路由的理解吧恨诱。

上面已經(jīng)說了上面是路由媳瞪,而路由本身也經(jīng)歷了不同的發(fā)展階段:

  1. 后端路由
  2. 前端路由

后端路由又可稱之為服務(wù)器端路由,因為對于服務(wù)器來說照宝,當(dāng)接收到客戶端發(fā)來的HTTP請求蛇受,就會根據(jù)所請求的相應(yīng)URL,來找到相應(yīng)的映射函數(shù)厕鹃,然后執(zhí)行該函數(shù)兢仰,并將函數(shù)的返回值發(fā)送給客戶端。對于最簡單的靜態(tài)資源服務(wù)器剂碴,可以認(rèn)為把将,所有URL的映射函數(shù)就是一個文件讀取操作。對于動態(tài)資源忆矛,映射函數(shù)可能是一個數(shù)據(jù)庫讀取操作察蹲,也可能是進(jìn)行一些數(shù)據(jù)的處理,等等。然后根據(jù)這些讀取的數(shù)據(jù)递览,在服務(wù)器端就使用相應(yīng)的模板來對頁面進(jìn)行渲染后叼屠,再返回渲染完畢的頁面。這種方式在早期的前端開發(fā)中非常普遍绞铃,它的好處與壞處都很明顯:

  • 好處:安全性好镜雨,SEO好。
  • 缺點:加大服務(wù)器的壓力儿捧,不利于用戶體驗荚坞,代碼冗合。

也正是由于后端路由還存在著自己的不足菲盾,前端路由才有了屬于自己的一片天地與發(fā)展的空間颓影。對于前端路由來說,路由的映射函數(shù)通常是進(jìn)行一些DOM的顯示和隱藏操作懒鉴。這樣诡挂,當(dāng)訪問不同的路徑的時候,會顯示不同的頁面組件临谱。前端路由主要有以下兩種實現(xiàn)方案:

  • hash
  • history API

當(dāng)然璃俗,前端路由也存在缺陷:使用瀏覽器的前進(jìn),后退鍵時會重新發(fā)送請求悉默,來獲取數(shù)據(jù)城豁,沒有合理地利用緩存。但總的來說抄课,現(xiàn)在前端路由已經(jīng)是實現(xiàn)路由的主要方式了唱星,我們常用的諸如react-router等前端框架的路由控制都是基于前端路由進(jìn)行開發(fā)的,因此將前端路由進(jìn)行一個了解
還是很有必要的跟磨。

二间聊、前端路由的實現(xiàn)

2.1 基于hash

早期的前端路由的實現(xiàn)就是基于location.hash來實現(xiàn)的。其實現(xiàn)原理也很簡單抵拘,location.hash的值就是URL中#后面的內(nèi)容哎榴。比如下面這個網(wǎng)站,它的location.hash='#me':

https://www.srtian.com#me

此外仑濒,hash也存在下面幾個特性:

  • URL中hash值只是客戶端的一種狀態(tài)叹话,也就是說當(dāng)向服務(wù)器端發(fā)出請求時,hash部分不會被發(fā)送墩瞳。
  • hash值的改變驼壶,都會在瀏覽器的訪問歷史中增加一個記錄。因此我們能通過瀏覽器的回退喉酌、前進(jìn)按鈕控制hash的切換热凹。
  • 我們可以使用hashchange事件來監(jiān)聽hash的變化泵喘。

出發(fā)hsah變化的方式也有兩種,一種是通過a標(biāo)簽般妙,并設(shè)置href屬性纪铺,當(dāng)用戶點擊這個標(biāo)簽后,URL就會發(fā)生改變碟渺,也就會觸發(fā)hashchange事件了:

<a href="#srtian">srtian</a>

還有一種方式就是直接使用JavaScript來對loaction.hash進(jìn)行賦值鲜锚,從而改變URL,觸發(fā)hashchange事件:

location.hash="#srtian"

2.2 基于History API

前面的hash雖然也很不錯苫拍,但使用時都需要加上#芜繁,并不是很美觀。因此到了HTML5绒极,又提供了History API來實現(xiàn)URL的變化骏令。其中做最主要的API有以下兩個:history.pushState()和history.repalceState()。

這兩個API可以在不進(jìn)行刷新的情況下垄提,操作瀏覽器的歷史紀(jì)錄榔袋。唯一不同的是,前者是新增一個歷史記錄铡俐,后者是直接替換當(dāng)前的歷史記錄凰兑。此外,這兩個api都接受三個參數(shù):

window.history.pushState(null, null, "http://www.163.com");
  • 狀態(tài)對象(state object):一個JavaScript對象高蜂,與用pushState()方法創(chuàng)建的新歷史記錄條目關(guān)聯(lián)聪黎。無論何時用戶導(dǎo)航到新創(chuàng)建的狀態(tài)罕容,會觸發(fā)popstate事件备恤,并能在事件中使用該對象。
  • 標(biāo)題(title):一般瀏覽器會忽略锦秒,最好傳入null露泊。
  • 地址(URL):就是需要新增的歷史記錄的地址,瀏覽器不會去直接加載改地址旅择,但后面也可能會去嘗試加載該地址惭笑。此外需要注意的是,傳入的URL與當(dāng)前URL應(yīng)該是同源的生真。

這一塊的詳情可以去看MDN沉噩,它做了一個比較詳細(xì)的介紹:

https://developer.mozilla.org/en-US/docs/Web/API/History

此外,還提供了popstate事件來監(jiān)聽歷史記錄的變化柱蟀。

可以看看下面這個實例:

<p id="example">
 <a href="/name" title="name">name</a>
 <a href="/age" title="age">age</a>?
</p>
<div class="main" id="main"></div>
<script>
;(function(){
    var examplebox = document.getElementById('example')
    var mainbox = document.getElementById('main')
    
    examplebox.addEventListener('click', function(e){
        e.preventDefault()
        var elm = e.target
        var uri = elm.href
        var tlt = elm.title
        history.pushState({path:uri,title:tlt}, null, uri)
        mainbox.innerHTML = 'current page is '+tlt
    })
    window.addEventListener('popstate',function(e){
        var state = e.state
        mainbox.innerHTML = 'current page is ' + state.title
    })
})()
</script>

兩種實現(xiàn)方式的對比:基于Hash的路由實現(xiàn)川蒙,兼容性更好;而基于History API的路由长已,則更正式畜眨,更美觀昼牛,可以設(shè)置與當(dāng)前URL同源的任意URL,路徑更直觀康聂。此外贰健,基于Hash的路由不需要對服務(wù)器做改動,基于History API的路由需要對服務(wù)器做一些改造恬汁,需要對不同的路由進(jìn)行相應(yīng)的設(shè)置才行伶椿。

三、React-Router

由于我現(xiàn)在也就對React-Router比較熟悉氓侧,Vue學(xué)了太久了悬垃,忘記了。Angular剛學(xué)甘苍,還沒到路由這塊這來尝蠕,因此就以React-Router為例,來聊聊現(xiàn)代前端框架的路由實現(xiàn)思路载庭。先來看看一個簡單的React中的Router代碼:

<Router>
    <Switch>
        <Route path="/about" component={About}/> 
        <Route path="/:user" component={User}/> 
    </Switch> 
</Router>

其實現(xiàn)思路也很簡單如下圖所示:


image

其實現(xiàn)思路很簡單:About和User這兩個component一直都存在看彼。當(dāng)路由發(fā)生改變時,與URL相匹配的component機(jī)會被成功渲染囚聚。而不匹配的component就設(shè)置為null靖榕。

具體實現(xiàn),大家可以看這篇文章顽铸,這位大佬做了很詳細(xì)的介紹:

https://github.com/youngwind/blog/issues/109

參考資料:

https://github.com/youngwind/blog/issues/109

https://zhuanlan.zhihu.com/p/24814675

https://segmentfault.com/a/1190000007238999

http://www.cnblogs.com/yuqing6/p/6731980.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末茁计,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子谓松,更是在濱河造成了極大的恐慌星压,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鬼譬,死亡現(xiàn)場離奇詭異娜膘,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)优质,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門竣贪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人巩螃,你說我怎么就攤上這事演怎。” “怎么了避乏?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵爷耀,是天一觀的道長。 經(jīng)常有香客問我淑际,道長畏纲,這世上最難降的妖魔是什么扇住? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮盗胀,結(jié)果婚禮上艘蹋,老公的妹妹穿的比我還像新娘。我一直安慰自己票灰,他們只是感情好女阀,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著屑迂,像睡著了一般浸策。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惹盼,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天庸汗,我揣著相機(jī)與錄音,去河邊找鬼手报。 笑死蚯舱,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的掩蛤。 我是一名探鬼主播枉昏,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼揍鸟!你這毒婦竟也來了兄裂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤阳藻,失蹤者是張志新(化名)和其女友劉穎晰奖,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體稚配,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡畅涂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年港华,在試婚紗的時候發(fā)現(xiàn)自己被綠了道川。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡立宜,死狀恐怖冒萄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情橙数,我是刑警寧澤尊流,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站灯帮,受9級特大地震影響崖技,放射性物質(zhì)發(fā)生泄漏逻住。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一迎献、第九天 我趴在偏房一處隱蔽的房頂上張望瞎访。 院中可真熱鬧,春花似錦吁恍、人聲如沸扒秸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伴奥。三九已至,卻和暖如春翼闽,著一層夾襖步出監(jiān)牢的瞬間拾徙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工感局, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留锣吼,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓蓝厌,卻偏偏與公主長得像玄叠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拓提,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容