vue-router history模式的實(shí)現(xiàn)原理

? ? ? ? 各位客爺大家好,疫情已經(jīng)肆虐了我們大半年的時間了鉴吹,不知各位有沒有在這個非常時期逆流而上找到自己心儀的工作呢~

? ? ? ? 在下今天主要來和各位一起討論一下vue-router history模式的實(shí)現(xiàn)方法

? ? ? ? 一豆励,經(jīng)典案例

? ? ? ? 事情的起因還要追溯于近期的一次提測瞒渠,切換場景(一個真實(shí)的case,如果您只想get干貨可以越過人生分割線來忽略):

? ? ? ? ———————————————? 人生分割線? ? —————————————————

? ? ? ? 我司的后臺系統(tǒng)使用vue+vue-router這種技術(shù)棧來實(shí)現(xiàn)嫩痰,由于業(yè)務(wù)需求較多串纺,這些頁面也就多到左側(cè)菜單欄無法承載的地步纺棺,所以我們每個人可見的左側(cè)顯示菜單邪狞,都是通過一個權(quán)限系統(tǒng)配制而成的帆卓。

大概是長這個樣子吧

? ? ? ? 左側(cè)的菜單欄點(diǎn)擊鏈接之后跳轉(zhuǎn)方式是window.location.href鳞疲,這次我們重構(gòu)將之前的hash模式改為了history模式,但是問題來了:

? ? ? ? 由于之前系統(tǒng)一直是以hash模式url跳轉(zhuǎn)蠕蚜,所以后臺配置的路徑一直是hash試的全路徑尚洽,例如:

? ? ? ? ? ? ? ? http://XXX.com/#home

? ? ? ? ? ? ? ? http://XXX.com/#list

? ? ? ? 但是當(dāng)我們改為了history模式之后(http://XXX.com/list),問題出現(xiàn)了靶累,每一次頁面跳轉(zhuǎn)都造成了頁面刷新腺毫。

? ? ? ? 我在這個跳轉(zhuǎn)邏輯里發(fā)現(xiàn)其實(shí)之前其實(shí)是有history模式的兼容的癣疟,只要從后臺配置的路徑不是全url路徑,是一個path的話潮酒,那就會使用vue-router的push方法跳轉(zhuǎn)睛挚,于是這個問題算是解決了。但是當(dāng)我們組妹子嬌嬌問我為什么之前使用全路徑都OK的時候急黎,我只是回復(fù)了她一句因?yàn)橹笆莌ash模式扎狱,如果換位思考的話,我對這個回答并不滿意勃教,因此我想通過這篇博文整體解釋一下為什么之前使用hash模式可以,但是history會出現(xiàn)問題。

? ? ? ? ————————————————? 人生分割線? ? ————————————————

? ? ? ? 二印机,原理分析

? ? ? ? 終于要上干貨了,我們來針對這幾個問題一一分析:

? ? ? ? 1咒劲,為什么之前hash模式,菜單配置全路徑頁面跳轉(zhuǎn)不刷新蛔屹?

? ? ? ? ? ? 根據(jù)http協(xié)議所示,url中hash改變請求是不會發(fā)送到服務(wù)端的育叁,不管你怎么location跳轉(zhuǎn),或者url上直接加上hash值回車隐锭,他都一樣固執(zhí),就是不和服務(wù)器老大說。

? ? ? ? ? ? 但是我們的系統(tǒng)里又引入了vue-router樱溉,其中hashchange這個事件監(jiān)聽又監(jiān)聽到了hash的變化撩嚼,從而觸發(fā)了組件的更新,也就繪制出了相應(yīng)的頁面逻族。

? ? ? ? 2要拂,為什么換成history模式搏嗡,每次點(diǎn)擊菜單的導(dǎo)航都會頁面刷新?

? ? ? ? ? ? 首先我們來看一下一個正確的history模式下磅氨,首頁刷新到顯示的整體流程:

? ? ? ? ? ? ? ? 1悍赢,將這個完整的url發(fā)到服務(wù)器ng

? ? ? ? ? ? ? ? 2,ng需要配置用這個uri再指給給前端index.html(這里我插一句哈,為什么要這么做呢,因?yàn)楦緵]有任何一個服務(wù)器提供了這個url路由糕再,如果直接訪問的話就是404究抓,所以需要指回給前端绑嘹,讓前端自己去根據(jù)path來顯示)

? ? ? ? ? ? ? ? 3,此時ng將這個請求指向了前端index.html,index.html中開始加載js惕鼓,js中已有vue-router的代碼一膨,vue-router自動觸發(fā)了popstate這個事件价淌,在這個事件回調(diào)中括尸,繪制了這個path下對應(yīng)的頁面組件

? ? ? ? ? ? 接著我們再來看一下vue-router push方法的頁面跳轉(zhuǎn)流程:

? ? ? ? ? ? ? ? 1啦膜,vue-router調(diào)用push方法首先會使用pushstate變換頁面url(僅僅變化url雀摘,頁面不變)

? ? ? ? ? ? ? ? 2乘粒,緊接著根據(jù)push方法中傳入的params找到對應(yīng)的組件【頁面】

? ? ? ? ? ? ? ? 3轧铁,載入對應(yīng)頁面組件绑洛,跳轉(zhuǎn)完畢

? ? ? ? ? ? 【劃重點(diǎn)】vue-router的push跳轉(zhuǎn)或者replace跳轉(zhuǎn)是不需要請求服務(wù)器的绑蔫!

? ? ? ? ? ? 但是我們?nèi)绻褂脀indow.location.href來做這個頁面跳轉(zhuǎn)篓叶,就基本上和web1.0沒什么區(qū)別,一定會先請求到服務(wù)器,再由服務(wù)器下發(fā)資源匹摇,導(dǎo)致頁面刷新~

? ? ? ? ? ? 講到這里我想妹子和我的困惑也都迎刃而解了坡垫,最近也有面試過一些前端溉卓,簡歷上也都有寫搞過vue-router的history模式爆阶,配置ng之類的徒役,但是當(dāng)我問為什么配上ng就可以正常訪問了,或者說ng是怎么實(shí)現(xiàn)頁面正常訪問的,基本上都能刷下一大波养匈,在下認(rèn)為搞技術(shù)的話一定要有敬畏之心猬仁,做項(xiàng)目要嚴(yán)謹(jǐn)诈闺,不能淺嘗輒止#@$!^$#&%.....

? ? ? ? ? ? 如果各位還想聽在下聊聊vue-router中使用的pushState方法的話漓穿,請越過下面的漲芝士分割線僚饭,如果已經(jīng)對這部分了如指掌的話击罪,那么就祝您找到自己稱心的工作了

? ? ? ? ————————————————? 漲芝士分割線? ? ————————————————

? ? ? ? 三竣稽,知識點(diǎn)討論

? ? ? ? ? ? 在下剛開始用 vue-router 的時候就好奇岛宦,為什么$router跳轉(zhuǎn)頁面的時候api是push,這分明是一個數(shù)組的方法嘛~但是后來在下閱讀了vue-router的源碼,發(fā)現(xiàn)猶大是用了pushState來做純前端的頁面跳轉(zhuǎn),在下不禁拍了下大腿署咽,我*高招啊饱须。

? ? ? ? ? ? 這個pushState單純的做了一個url的變化督怜,并且在路由隊列里加上了這條新的url的記錄屉凯,所以如果您在page1頁面使用了pushState這個方法灌旧,頁面不會變化,只是瀏覽器地址欄會發(fā)生更新,且瀏覽器的回退按鈕變成了可點(diǎn)擊狀態(tài)!

? ? ? ? ? ? 所以啸蜜,猶大在使用pushState將url改變之前拇泣,先做了頁面組件的刷新债朵,也就模擬出了頁面跳轉(zhuǎn)的樣子。

? ? ? ? ? ? 那么,如果我刷新首頁蔽莱,又或者前進(jìn)后退仪糖,怎么再更新頁面組件呢?答案就是使用popstate來做事件監(jiān)聽劲室,當(dāng)用戶首次訪問,前進(jìn)或后退的時候确买,都會觸發(fā)popstate事件铛楣,再由popstate來做當(dāng)前頁,上一頁等頁面的記錄和繪制缩焦。

—————————————————? 漲芝士分割線? —————————————————

? ? ? ? 今天就聊到這了葱轩,最近疫情北京又變中高風(fēng)險地區(qū)了,本來和老婆打算去玩?zhèn)€迪士尼來慶祝下一周年,看來也泡湯了本谜。最近公司組織架構(gòu)調(diào)整偎窘,我們部門在風(fēng)波中也被撕扯分裂到了各個新項(xiàng)目組他托,之前一起并肩奮斗的小伙伴也走了一小半把篓,但是至少窖铡,我們還有張照片~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末氧映,一起剝皮案震驚了整個濱河市振峻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌择份,老刑警劉巖扣孟,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異荣赶,居然都是意外死亡凤价,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進(jìn)店門拔创,熙熙樓的掌柜王于貴愁眉苦臉地迎上來利诺,“玉大人,你說我怎么就攤上這事剩燥÷猓” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵躏吊,是天一觀的道長氛改。 經(jīng)常有香客問我,道長比伏,這世上最難降的妖魔是什么胜卤? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮赁项,結(jié)果婚禮上葛躏,老公的妹妹穿的比我還像新娘。我一直安慰自己悠菜,他們只是感情好舰攒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著悔醋,像睡著了一般摩窃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芬骄,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天猾愿,我揣著相機(jī)與錄音,去河邊找鬼账阻。 笑死蒂秘,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的淘太。 我是一名探鬼主播姻僧,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼规丽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了撇贺?” 一聲冷哼從身側(cè)響起赌莺,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎显熏,沒想到半個月后雄嚣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡喘蟆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年缓升,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蕴轨。...
    茶點(diǎn)故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡港谊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出橙弱,到底是詐尸還是另有隱情歧寺,我是刑警寧澤,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布棘脐,位于F島的核電站斜筐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蛀缝。R本人自食惡果不足惜顷链,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望屈梁。 院中可真熱鬧嗤练,春花似錦、人聲如沸在讶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽构哺。三九已至革答,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間曙强,已是汗流浹背残拐。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旗扑,地道東北人蹦骑。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓慈省,卻偏偏與公主長得像臀防,于是被迫代替她去往敵國和親眠菇。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評論 2 356