(一)定義(頁面之間的跳轉)
後端路由:通過用戶請求的url導航到具體的html頁面;每跳轉到不同的URL,都是重新訪問服務端,然後服務端返回頁面,頁面也可以是服務端獲取數據,然後和模板組合,返回HTML;也可以是直接返回模板HTML,然後由前端js再去請求數據,使用前端模板和數據進行組合,生成想要的HTML
前端路由:前端單頁應用 SPA(Single Page Application)中,路由描述的是 URL 與 UI 之間的映射關係,這種映射是單向的,即 URL 變化引起 UI 更新(無需刷新頁面)
(二)對比
1.從性能和用戶體驗的層面來比較的話,後端路由每次訪問一個新頁面的時候都要向服務器發送請求,然後服務器再響應請求,這個過程肯定會有延遲。而前端路由在訪問一個新頁面的時候僅僅是變換了一下路徑而已,沒有了網絡延遲,對於用戶體驗來說會有相當大的提升。
(三)前端路由實現方式
hash實現:
1.hash 是 URL 中 hash (#) 及後面的那部分,常用作錨點在頁面內進行導航,改變 URL 中的 hash 部分不會引起頁面刷新;
2.通過 hashchange 事件監聽 URL 的變化,改變 URL 的方式只有這幾種:通過瀏覽器前進後退改變 URL、通過<a>
標籤改變 URL、通過window.location改變URL,這幾種情況改變 URL 都會觸發 hashchange 事件
history實現:
1.history 提供了 pushState 和 replaceState 兩個方法,這兩個方法改變 URL 的 path 部分不會引起頁面刷新
2.history 提供類似 hashchange 事件的 popstate 事件,但 popstate 事件有些不同:通過瀏覽器前進後退改變 URL 時會觸發 popstate 事件,通過pushState/replaceState或<a>
標籤改變 URL 不會觸發 popstate 事件。好在我們可以攔截 pushState/replaceState的調用和<a>
標籤的點擊事件來檢測 URL 變化,所以監聽 URL 變化可以實現,只是沒有 hashchange 那麼方便。
hash實現方式:(#號)
HTML 部分:
<body>
<ul>
<!-- 定義路由 -->
<li><a href="#/home">home</a></li>
<li><a href="#/about">about</a></li>
<!-- 渲染路由對應的 UI -->
<div id="routeView"></div>
</ul>
</body>
JavaScript 部分:
// 頁面加載完不會觸發 hashchange,這裏主動觸發一次 hashchange 事件
window.addEventListener('DOMContentLoaded', onLoad)
// 監聽路由變化
window.addEventListener('hashchange', onHashChange)
// 路由視圖
var routerView = null
function onLoad () {
routerView = document.querySelector('#routeView')
onHashChange()
}
// 路由變化時,根據路由渲染對應 UI
function onHashChange () {
switch (location.hash) {
case '#/home':
routerView.innerHTML = 'Home'
return
case '#/about':
routerView.innerHTML = 'About'
return
default:
return
}
}
history實現方式:(/)
HTML 部分:
<body>
<ul>
<li><a href='/home'>home</a></li>
<li><a href='/about'>about</a></li>
<div id="routeView"></div>
</ul>
</body>
JavaScript 部分:
// 頁面加載完不會觸發 hashchange,這裏主動觸發一次 hashchange 事件
window.addEventListener('DOMContentLoaded', onLoad)
// 監聽路由變化
window.addEventListener('popstate', onPopState)
// 路由視圖
var routerView = null
function onLoad () {
routerView = document.querySelector('#routeView')
onPopState()
// 攔截 <a> 標籤點擊事件默認行爲, 點擊時使用 pushState 修改 URL並更新手動 UI,從而實現點擊鏈接更新 URL 和 UI 的效果。
var linkList = document.querySelectorAll('a[href]')
linkList.forEach(el => el.addEventListener('click', function (e) {
e.preventDefault()
history.pushState(null, '', el.getAttribute('href'))
onPopState()
}))
}
// 路由變化時,根據路由渲染對應 UI
function onPopState () {
switch (location.pathname) {
case '/home':
routerView.innerHTML = 'Home'
return
case '/about':
routerView.innerHTML = 'About'
return
default:
return
}
}