之前博客地址發生更改,重新發布!
在傳統網站開發中,我們一般使用比如asp、php、jsp等技術進行開發,開發完成后統一部署在服務器上,我們訪問時,會在瀏覽器中發送帶有'.asp','.php','.jsp'等后綴路徑的url請求,服務器會根據對應的路由映射表,找到我們請求的頁面并渲染成HTML,然后把HTML頁面直接回傳給瀏覽器展示,這就是所謂的服務器端渲染SSR(Server Side Render),
然而隨著前端頁面復雜性的提高以及前端技術的興起(尤其是Ajax技術的興起),行業內越來越推崇前后端分離的開發模式,使服務器端不在關注HTML頁面的渲染,而是只專注于邏輯的開發,通過Api提供資料;前端只專注于UI的開發,把從服務器請求的資料生成DOM插入到頁面中去,從服務器請求資料,然后由客戶端通過前端技術生成展示頁面的方式就是客戶端渲染CSR(Client Side Render),
客戶端渲染使前后端進行了分離,各自只關注屬于自己的部分,并且使用戶體驗也得到了提升,用戶互動不用每次都重繪頁面,基于這些優點,單頁應用(SPA(Single Page Web Application))的開發模型備受青睞,可以做到動態重寫當前頁面來與用戶互動,而不需要重新加載整個頁面,然而要實作單頁應用,做到互動和跳轉都不需要重繪的體驗,需要解決一個重要問題,就是路由問題,所以就有了前端路由,其實前端路由是相對于服務器端路由的稱謂,由前端控制維護url和UI之間的映射關系,url更改后引起ui更新,而無需重繪頁面,
下面就讓我們通過兩種方式實作前端路由:
實作前端路由的整體思路:
首先維護一張包含path和對應的頁面內容的路由映射表,當監聽到路由發生變化后,從路由映射表中篩選出對應的路由資訊,并把路由資訊中對應的內容頁面渲染添加到html頁面展示,開始之前先了解下兩種方式的基本知識,
1.window.history
Window.history是一個只讀屬性,用來獲取包含操作瀏覽器會話歷史History 物件,
主要方法:
back()
前往上一頁, 用戶可點擊瀏覽器左上角的回傳按鈕模擬此方法. 等價于 history.go(-1)
forward()
在瀏覽器歷史記錄里前往下一頁,用戶可點擊瀏覽器左上角的前進按鈕模擬此方法. 等價于 history.go(1)
go()
通過當前頁面的相對位置從瀏覽器歷史記錄( 會話記錄 )加載頁面
pushState()
按指定的名稱和URL(如果提供該引數)將資料push進會話歷史堆疊,資料被DOM進行不透明處理;你可以指定任何可以被序列化的javascript物件,
replaceState()
按指定的資料,名稱和URL(如果提供該引數),更新歷史堆疊上最新的入口,這個資料被DOM 進行了不透明處理,你可以指定任何可以被序列化的javascript物件,
2.location.hash
hash 屬性是一個可讀可寫的字串,該字串是 URL 的錨部分(從 # 號開始的部分),
實作代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>window.history路由</title>
</head>
<body>
<div>
<div id="routerLink">
<div>
<button onclick="historyChange('home')">首頁(history)/button>
<button onclick="historyChange('about')">關于(history)</button>
</div>
<div>
<button onclick="hashChange('home')">首頁(hash)</button>
<button onclick="hashChange('about')">關于(hash)</button>
</div>
</div>
<div>
<div id="routerView">
</div>
</div>
</div>
<!-- 2.創建子視圖模板 -->
<template id="home">
<div>hello,我是首頁</div>
</template>
<template id="about">
<div>hello,我是關于</div>
</template>
<script>
//1.首先創建路由表
const routerTable = [
{
path: 'home',
component: '#home'
},
{
path: 'about',
component: '#about'
}
]
//*********** 方式一:window.history **************
//3.(window.history)監聽路由更改,根據新路由path加載對應的內容
function historyChange(path) {
render({ path: path })
}
//添加popstate狀態監聽
window.addEventListener('popstate', function (e) {
if (e) {
render({ path: e.state, isPush: false })
}
})
//************** 方式二:location.hash ***************
function hashChange(path) {
render({ path: path, mode: 'hash' })
}
//添加hashchange監聽
window.addEventListener('hashchange', function () {
let path = location.hash
//path移除開始的#
render({ path: path.substring(1, path.length - 2), mode: 'hash' })
})
//**************公共方法*******************
//渲染方法
function render(data) {
//默認值,mode默認為history,isPush=true,isReplace=false,path=home
data = Object.assign({ mode: 'history', isPush: true, isReplace: false, path: 'home' }, data)
if (data.path) {
//查詢路由資訊
const route = routerTable.find(p => p.path == data.path);
if (route) {
if (data.mode == 'history') {
if (data.isPush) {
//更改url---后退、前進不更改
if (data.isReplace) {
window.history.replaceState(data.path, '', data.path)
} else {
window.history.pushState(data.path, '', data.path)
}
}
} else if (data.mode == 'hash') {
location.hash = data.path
}
//更新html
document.querySelector("#routerView").innerHTML = document.querySelector(route.component).innerHTML
}
}
}
</script>
</body>
</html>
PS:需要用http的方式運行頁面,要不然pushState是無法使用的,會報:cannot be created in a document with origin 'null'的錯誤,
不過如果你電腦上已經安裝了vscode,可以下載Live Server插件,來運行html檔案,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/104029.html
標籤:JavaScript
