談談你對前端路由的理解
來自:掘金
作者:尼克陳
鏈接:https://juejin.cn/post/6917523941435113486
一篇文章,不可能做的面面俱到,全部受衆。希望大家帶着發散思維去看文章,將文章涉及的知識點,吸收爲己所用。這樣看完一篇文章,纔能有所收穫。
前言
1、爲什麼會出現前端路由。
2、前端路由解決了什麼問題。
3、前端路由實現的原理是什麼。
我們帶着這三個問題,繼續往下看,閱讀的過程中如果同學們有自己的見解,可以評論區發表自己的看法。如果覺得講的內容讓你有了新的見解,請獻上你寶貴的一讚👍,這將是我繼續寫作的動力。
傳統頁面
這裏不糾結叫法,凡是整個項目都是 DOM
直出的頁面,我們都稱它爲 “傳統頁面”(SSR 屬於首屏直出,這裏我不認爲是傳統頁面的範疇)。那麼什麼是 DOM
直出呢?簡單說就是在瀏覽器輸入網址後發起請求,返回來的 HTML
頁面是最終呈現的效果,那就是 DOM
直出。並且每次點擊頁面跳轉,都會重新請求 HTML
資源。耳聽爲虛,眼見爲實。我們以這個地址爲例,驗證以下上述說法。
www.cnblogs.com/han-1034683…
定眼一看,就能明白上圖在描述什麼。沒錯,博客園就是一個傳統頁面搭建而成的網站,每次加載頁面,都會返回 HTML
資源以及裏面的 CSS
等靜態資源,組合成一個新的頁面。
“瞎了” 的同學,我再教一個方法,就是在瀏覽器頁面右鍵,點擊 “顯示網頁源代碼”,打開後如下所示:
網頁上能看到什麼圖片或文字,你能在上述圖片中找到相應的 HTML
結構,那也屬於傳統頁面,也就是 DOM
直出。
單頁面
時代在進步,科技在發展,面對日益增長的網頁需求,網頁開始走向模塊化、組件化的道路。隨之而來的是代碼的難以維護、不可控、迭代艱難等現象。面臨這種情況,催生出不少優秀的現代前端框架,首當其衝的便是 React
、 Vue
、 Angular
等著名單頁面應用框架。而這些框架有一個共同的特點,便是 “通過 JS 渲染頁面”。
舉個例子,以前我們直出 DOM
,而現在運用這些單頁面框架之後, HTML
頁面基本上只有一個 DOM
入口,大致如下所示:
所有的頁面組件,都是通過運行上圖底部的 app.js
腳本,掛載到 <div></div>
這個節點下面。用一個極其簡單的 JS 展示掛載這一個步驟:
image.png
脫去所有的凡塵世俗,最本真的單頁項目運行形式便是如此。注意,我要點題了啊!!!
既然單頁面是這樣渲染的,那如果我有十幾個頁面要互相跳轉切換,咋整!!??這時候 前端路由 應運而生,它的出現就是爲了解決單頁面網站,通過切換瀏覽器地址路徑,來匹配相對應的頁面組件。我們通過一張醜陋的圖片來理解這個過程:
前端路由 會根據瀏覽器地址欄 pathname
的變化,去匹配相應的頁面組件。然後將其通過創建 DOM
節點的形式,塞入根節點 <div></div>
。這就達到了無刷新頁面切換的效果,從側面也能說明正因爲無刷新,所以 React
、 Vue
、 Angular
等現代框架在創建頁面組件的時候,每個組件都有自己的 生命週期 。
原理
前端路由 插件比較火的倆框架對應的就是 Vue-Router
和 React-Router
, 但是它們的邏輯,歸根結底還是一樣的,用殊途同歸四個字,再合適不過。
通過分析哈希模式和歷史模式的實現原理,讓大家對前端路由的原理有一個更深刻的理解。
哈希模式
a
標籤錨點大家應該不陌生,而瀏覽器地址上 #
後面的變化,是可以被監聽的,瀏覽器爲我們提供了原生監聽事件 hashchange
,它可以監聽到如下的變化:
-
點擊
a
標籤,改變了瀏覽器地址 -
瀏覽器的前進後退行爲
-
通過
window.location
方法,改變瀏覽器地址
接下來我們利用這些特點,去實現一個 hash
模式的簡易路由:在線運行
當然,這是很簡單的實現,真正的 hash 模式,還要考慮到很多複雜的情況,大家有興趣就去看看源碼。
瀏覽器展示效果如下:
歷史模式
history
模式會比 hash
模式稍麻煩一些,因爲 history
模式依賴的是原生事件 popstate
,下面是來自 MDN 的解釋:
image.png
小知識:pushState 和 replaceState 都是 HTML5 的新 API,他們的作用很強大,可以做到改變瀏覽器地址卻不刷新頁面。這是實現改變地址欄卻不刷新頁面的重要方法。
包括 a
標籤的點擊事件也是不會被 popstate
監聽。我們需要想個辦法解決這個問題,才能實現 history
模式。
image.png
** 解決思路:** 我們可以通過遍歷頁面上的所有 a
標籤,阻止 a
標籤的默認事件的同時,加上點擊事件的回調函數,在回調函數內獲取 a
標籤的 href
屬性值,再通過 pushState
去改變瀏覽器的 location.pathname
屬性值。然後手動執行 popstate
事件的回調函數,去匹配相應的路由。邏輯上可能有些饒,我們用代碼來解釋一下:在線地址
這裏注意,不能在瀏覽器直接打開靜態文件,需要通過 web 服務,啓動端口去瀏覽網址。
總結
這篇文章主要知識點集中在前端路由這塊,能完全看完,並且把實現原理捋一遍,我想你應該對現代前端框架會有一個新的理解。沒有新的理解的同學,來杭州打我,我不還手。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/uPs-aClWh1N-9zGFXXNCDg