在傳統網站開發中,咱們通常使用好比asp、php、jsp等技術進行開發,開發完成後統一部署在服務器上,咱們訪問時,會在瀏覽器中發送帶有'.asp','.php','.jsp'等後綴路徑的url請求,服務器會根據對應的路由映射表,找到咱們請求的頁面並渲染成HTML,而後把HTML頁面直接返回給瀏覽器展現,這就是所謂的服務器端渲染SSR(Server Side Render)。javascript
然而隨着前端頁面複雜性的提升以及前端技術的興起(尤爲是Ajax技術的興起),行業內愈來愈推崇先後端分離的開發模式。使服務器端不在關注HTML頁面的渲染,而是隻專一於邏輯的開發,經過Api提供數據;前端只專一於UI的開發,把從服務器請求的數據生成DOM插入到頁面中去。從服務器請求數據,而後由客戶端經過前端技術生成展現頁面的方式就是客戶端渲染CSR(Client Side Render)。php
客戶端渲染使先後端進行了分離,各自只關注屬於本身的部分,而且使用戶體驗也獲得了提高,用戶交互不用每次都刷新頁面。基於這些優勢,單頁應用(SPA(Single Page Web Application))的開發模型備受青睞。能夠作到動態重寫當前頁面來與用戶交互,而不須要從新加載整個頁面。然而要實現單頁應用,作到交互和跳轉都不須要刷新的體驗,須要解決一個重要問題,就是路由問題。因此就有了前端路由,其實前端路由是相對於服務器端路由的稱謂,由前端控制維護url和UI之間的映射關係,url更改後引發ui更新,而無需刷新頁面。html
下面就讓咱們經過兩種方式實現前端路由:前端
實現前端路由的總體思路:
首先維護一張包含path和對應的頁面內容的路由映射表,當監聽到路由發生變化後,從路由映射表中篩選出對應的路由信息,並把路由信息中對應的內容頁面渲染添加到html頁面展現。開始以前先了解下兩種方式的基本知識。java
Window.history是一個只讀屬性,用來獲取包含操做瀏覽器會話歷史History 對象。
主要方法:
back()
前往上一頁, 用戶可點擊瀏覽器左上角的返回按鈕模擬此方法. 等價於 history.go(-1)
forward()
在瀏覽器歷史記錄裏前往下一頁,用戶可點擊瀏覽器左上角的前進按鈕模擬此方法. 等價於 history.go(1)
go()
經過當前頁面的相對位置從瀏覽器歷史記錄( 會話記錄 )加載頁面
pushState()
按指定的名稱和URL(若是提供該參數)將數據push進會話歷史棧,數據被DOM進行不透明處理;你能夠指定任何能夠被序列化的javascript對象。
replaceState()
按指定的數據,名稱和URL(若是提供該參數),更新歷史棧上最新的入口。這個數據被DOM 進行了不透明處理。你能夠指定任何能夠被序列化的javascript對象。後端
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文件。前後端分離
CSR-jsp