淺談前端路由🏃

什麼是路由👻

當提到路由的時候你會想到什麼? 路由器?簡單來講,路由就是URL到函數的映射前端

路由這個概念最早是後端出現的vue

  • 早期的網站開發的全部頁面都是由服務器來進行渲染的,服務器直接生產渲染好的HTML頁面返回給客戶端顯示
  • 一個頁面有本身對應的URL,當你輸入URL的時候會將這個URL發送到服務器,服務器經過正則進行匹配處理,最終生成HTML和數據返回給前端
  • 以上就是後端路由,簡單來講路由就是用來跟後端服務器進行交互的一種方式
  • 可是這種方式很糟糕的狀況就是整個頁面都由後端人員來維護,若是前端人員須要開發頁面就要經過修改JSP等頁面進行修改,這種狀況下HTML頁面代碼和邏輯會混合在一塊兒,不管是編寫仍是維護都很糟糕和麻煩
  • 因而就出現了先後端分離的階段

先後端分離🚀

  • 隨着Ajax的出現,有了先後端分離的開發模式
  • 當咱們請求數據接口的時候,後端只提供API來返回數據,前端經過Ajax來獲取數據並渲染到頁面中
  • 這樣能夠很清晰的分配先後端的職責,讓前端專心於用戶的交互和可視化,讓後端專心於數據的處理

SPA(單頁Web應用)階段🍻

  • 在傳統的網頁中,每一個HTML文件都是一個完成的HTML頁面,每當訪問一個URL就要去服務端請求大量的數據,不僅僅增長了性能損耗還破換了用戶瀏覽體驗
  • SPA(單頁Web應用)中,單純的瀏覽器地址改變, 利用了JavaScript動態變換網頁內容,網頁不會重載
  • 簡單來講就是在單頁面Web網頁中, 頁面的切換就是視圖之間的切換
  • 其實SPA最主要的特色就是在先後端分離基礎上加了一層前端路由

前端路由的核心

  • 改變URL,可是頁面不進行總體的刷新
  • 而網站與用戶交互時不進行總體刷新的同時,能夠有局部的內容進行改變
  • 前端渲染把渲染的任務交給了瀏覽器,經過客戶端來解決頁面的構建,這個很大程度上緩解了服務端的壓力。並且配合前端路由,無縫的頁面切換體驗天然是對用戶友好的。

說了這麼多,那該如何實現呢?接下來講到的hash(哈希)模式和history模式就是前端路由的實現方式react

hash模式

  • hashURLhash(#)及後面的那部分,經常使用做錨點在頁面內進行導航,改變URL中的hash部分不會引發頁面刷新
  • 瀏覽器不會對#號後面的路徑對服務端發起路由請求,也就是說當你請求一個https://juejin.cn/#123https://juejin.cn/其實到服務端都是去請求https://juejin.cn/這個頁面的內容
  • hash的改變會經過觸發hashchange事件監聽URL的變化,來渲染對應的頁面,經過瀏覽器前進後退改變URL、經過標籤改變URL、經過window.location改變URL,這幾種狀況改變URL都會觸發hashchange事件

經常使用的APIvue-router

window.location.hash = '123' // 設置 url 的hash,會在當前url後加上 '#123'
let hash = window.location.hash  
console.log(hash) //#123
window.addEventListener('hashchange', function(){ 
    // 監聽hash變化
})
複製代碼

image.png

history模式

  • window.history屬性指向history對象,它表示當前窗口的瀏覽歷史
  • history對象保存了當前窗口訪問過的全部頁面網址,經過window.history.length能夠得出當前窗口一共訪問過幾個網址,經過window.history.state能夠獲得History堆棧最上層的狀態值
window.history.length //4
window.history.state //null
複製代碼

image.png

history模式中,URL不帶#號,那他看起來就和一般的URL同樣了,那該如何改變URL不引發頁面刷新呢?後端

那麼就須要用到在HTML5的規範中,history對象新增了的pushStatereplaceState兩個方法, 這兩個方法都接受三個參數(state, title, url)跨域

  • state:須要保存的數據對象,經過pushState方法能夠將該對象內容傳遞到新頁面中
  • title:指標題,但通常用不到,沒有瀏覽器能夠支持填null便可
  • url:設定新的歷史記錄的url,必須與當前頁面處在同一個域,不指定的話則爲當前的路徑,若是設置了一個跨域網址,則會報錯,這樣設計的目的是,防止惡意代碼讓用戶覺得他們是在另外一個網站上,由於這個方法不會致使頁面跳轉,url能夠是絕對路徑,也能夠是相對路徑

history.pushState()

  • 該方法能夠理解爲在歷史記錄添加一條記錄
let state={
    app:'sth'
}
window.history.pushState(state, '', '') 
console.log(window.history.state) //{app:"sth"}
console.log(window.history.length)//每執行一次pushState則會改變
複製代碼
  • url設置了跨域網址則會報錯

image.png

history.replaceState()

  • history.replaceState() 的使用與 history.pushState() 很是類似,區別在於 replaceState() 是修改了當前的歷史記錄項而不是新建一個。
let state={
    app:'sth'
}
window.history.replaceState(state, '', '') 
console.log(window.history.state) //{app:"sth"}
console.log(window.history.length)//每執行replaceState不會改變
複製代碼

因爲history.pushState()history.replaceState()能夠改變url同時,不會刷新頁面,因此在HTML5中的histroy也具有了實現前端路由的能力瀏覽器

兩種模式的比較👈

hash history
外觀 有些許醜 比較優雅
兼容性 兼容性較好,能夠兼容IE8 兼容性相對較差
錨點功能 由於是在url加#致使錨點失效 有效
設置URL 由於只可修改#後面的hash因此只可設置與當前同文檔的 URL 設置的新 URL 能夠是與當前 URL 同源的任意 URL
刷新限制 無需服務端配合 須要服務端配合

寫在最後👋

  • 前端路由的核心實現原理理解起來其實很簡單,可是結合具體框架後(vue-router,react-router),框架增長了不少特性,如動態路由、路由參數、路由動畫等等,這些致使路由實現變的複雜
  • 可是隻要真正理解了其中遇到問題也就迎刃而解了,在寫這篇文章的時候也讓我從新鞏固梳理了基礎,因此只要把學到的東西善於總結起來就會不斷擴充本身的大腦
  • 若是您以爲這篇文章有幫助到您的的話不妨點贊支持一下喲~~😛

參考

hash模式和history模式服務器

前端路由是什麼東西?markdown

相關文章
相關標籤/搜索