當提到路由的時候你會想到什麼? 路由器?簡單來講,路由就是URL
到函數的映射前端
路由這個概念最早是後端出現的vue
HTML
頁面返回給客戶端顯示URL
,當你輸入URL的時候會將這個URL
發送到服務器,服務器經過正則進行匹配處理,最終生成HTML和數據返回給前端JSP
等頁面進行修改,這種狀況下HTML
頁面代碼和邏輯會混合在一塊兒,不管是編寫仍是維護都很糟糕和麻煩SPA
(單頁Web
應用)中,單純的瀏覽器地址改變, 利用了JavaScript
動態變換網頁內容,網頁不會重載Web
網頁中, 頁面的切換就是視圖之間的切換SPA
最主要的特色就是在先後端分離基礎上加了一層前端路由URL
,可是頁面不進行總體的刷新說了這麼多,那該如何實現呢?接下來講到的hash
(哈希)模式和history
模式就是前端路由的實現方式react
hash
是URL
中hash(#)
及後面的那部分,經常使用做錨點在頁面內進行導航,改變URL
中的hash
部分不會引發頁面刷新#
號後面的路徑對服務端發起路由請求,也就是說當你請求一個https://juejin.cn/#123
和https://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變化
})
複製代碼
window.history
屬性指向history
對象,它表示當前窗口的瀏覽歷史history
對象保存了當前窗口訪問過的全部頁面網址,經過window.history.length
能夠得出當前窗口一共訪問過幾個網址,經過window.history.state
能夠獲得History
堆棧最上層的狀態值window.history.length //4
window.history.state //null
複製代碼
在history
模式中,URL
不帶#
號,那他看起來就和一般的URL
同樣了,那該如何改變URL
不引發頁面刷新呢?後端
那麼就須要用到在HTML5
的規範中,history
對象新增了的pushState
和replaceState
兩個方法, 這兩個方法都接受三個參數(state, title, url)
跨域
state
:須要保存的數據對象,經過pushState
方法能夠將該對象內容傳遞到新頁面中title
:指標題,但通常用不到,沒有瀏覽器能夠支持填null
便可url
:設定新的歷史記錄的url
,必須與當前頁面處在同一個域,不指定的話則爲當前的路徑,若是設置了一個跨域網址,則會報錯,這樣設計的目的是,防止惡意代碼讓用戶覺得他們是在另外一個網站上,由於這個方法不會致使頁面跳轉,url
能夠是絕對路徑,也能夠是相對路徑let state={
app:'sth'
}
window.history.pushState(state, '', '')
console.log(window.history.state) //{app:"sth"}
console.log(window.history.length)//每執行一次pushState則會改變
複製代碼
url
設置了跨域網址則會報錯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)
,框架增長了不少特性,如動態路由、路由參數、路由動畫等等,這些致使路由實現變的複雜前端路由是什麼東西?markdown