摘要:流行的今天不少同學(xué)會把前端路由跟后端路由弄混莫名其妙的怎么頁面啦之類奇怪的問題其實這就是沒弄清楚前端路由和后端路由的原因當(dāng)然你用當(dāng)我沒說本文所有前端路由都是的情況下不存在后端渲染好變量的情況原理首先我們看看前后端路由在瀏覽器中是怎么工作的上
spa流行的今天不少同學(xué)會把前端路由跟后端路由弄混, 莫名其妙的怎么頁面404啦之類"奇怪"的問題, 其實這就是沒弄清楚前端路由和后端路由的原因(當(dāng)然你用hash當(dāng)我沒說).
本文所有前端路由都是spa的情況下, 不存在后端渲染好變量的情況
原理首先我們看看前后端路由在瀏覽器中是怎么工作的, 上圖:
后端控制的路由:
我們可以知道后端其實返回的是html字符串, 也就是dom節(jié)點不出意外的話是確認(rèn)的. 不管你請求多少次, 結(jié)果都是確定的(get 冪等). 所以也就不存在404的情況
前端控制的路由:
如果是spa的話, 我們可以知道不管你請求那個頁面, 在后端處理好的情況下后端都會返回一個html文件(所謂單頁的由來), 靜態(tài)資源當(dāng)然也是類似的. 那么我們可能有點疑問, 比如一個個人主頁, 如果只返回一個html文件的話, 怎么得到不同的用戶資料呢, 答案就是前端路由(大部分情況, 不排除本地存儲?), js根據(jù)不同的路由再向服務(wù)器請求相關(guān)資料, 也就是說其實第一次服務(wù)端渲染我們的頁面是空的, 后期ajax請求. 所以我們看到很多單頁頁面打開了首先要loading一會. 就是在向服務(wù)器請求渲染頁面.
實現(xiàn)后端路由我們暫且不去管它, 我們看看是怎么實現(xiàn)的:
在非hash的情況下, 前端路由的實現(xiàn)基礎(chǔ)是window.history, 當(dāng)然我們不用去管它的兼容性了, 反正現(xiàn)在大部分瀏覽器能用就是了:
history有個重要的方法就是pushState, 其它的方法暫時用不到不提, 它的作用呢就是改變?yōu)g覽器地址欄里的地址, 以及在歷史紀(jì)錄里加上一條, 除此以外沒啥別的副作用了, 比如:
var stateObj = { foo: "bar" }; history.pushState(stateObj, "page 2", "bar.html");
上面的代碼只會跳到一個 bar.html的地址, 但是頁面本身并未跳轉(zhuǎn), 我們不是來講history對象本身的, 有興趣可以自行翻看mdn.
其實參考后端對路由的控制, 我們大略可以想像一個前端路由所具有的功能:
對路由做出響應(yīng)
渲染
一些事件, 比如beforeChange之類的
當(dāng)然我們現(xiàn)在一切從簡, 上面那些說清楚了起實現(xiàn)無非就是苦力了, 先給大家看看效果吧:
還是有點意思的吧.
下面是html代碼:
Document Panel heading without titlePanel content
index.js
const $routeController = $("a[data-role=custom-history]") const app = new Route() app.set("/1", function () { $("#app").html("1") }) app.set("/2", function () { $("#app").html(2) })
route.js
class Route { constructor () { this.urls = [] this.handles = {} window.addEventListener("popstate", (e) => { const state = e.state || {} const url = state.url || null if (url) { this.refresh(url) } }) const $routeController = $("a[data-role=custom-history]") $routeController.on("click", e => { e.preventDefault() const link = $(e.target).attr("href") history.pushState({ url: link }, "", link) this.refresh(link) }) } set (route, handle) { if (this.urls.indexOf(route) === -1) { this.urls.push(route) this.handles[route] = handle } } refresh (route) { if (this.urls.indexOf(route) === -1) throw new Error("請不要這樣調(diào)用, 路由表中不存在!") this.handles[route]() } }
按我的本意是不想在一篇文章里貼這么多代碼的, 但是因為也不可以直接嵌入jsbin之類的, 方便大家試試看效果, 就放進(jìn)來把, 因為代碼比較簡單, 而且深度綁定到了dom上, 就不要嘲笑啦!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/90561.html
摘要:在我轉(zhuǎn)前端以來,一直想要實現(xiàn)一個愿望自己搭建一個可以自動解析文檔的個人站今天終于實現(xiàn)啦,先貼上我的地址確認(rèn)需求其實一個最簡單的個人站,就是許多的頁面,你只要可以用寫出來就可以,然后掛到上。 在我轉(zhuǎn)前端以來,一直想要實現(xiàn)一個愿望: 自己搭建一個可以自動解析Markdown文檔的個人站 今天終于實現(xiàn)啦,先貼上我的blog地址 確認(rèn)需求 其實一個最簡單的個人站,就是許多的HTML頁面,你只要...
摘要:用來主要前臺的請求,并處理返回相關(guān)的數(shù)據(jù),做后臺服務(wù)。總結(jié)做完這個項目,其中的過程還是挺艱辛的,畢竟都是邊學(xué)邊做,不過最后能完成還是挺開心的,終于有了一個從到的項目過程。雖然只是一個小小的練手項目,不過對于目前的我,感覺還是不錯的。 showImg(https://oc1gyfe6q.qnssl.com/17-3-30/43434844-file_1490879850754_14751...
摘要:用來主要前臺的請求,并處理返回相關(guān)的數(shù)據(jù),做后臺服務(wù)。總結(jié)做完這個項目,其中的過程還是挺艱辛的,畢竟都是邊學(xué)邊做,不過最后能完成還是挺開心的,終于有了一個從到的項目過程。雖然只是一個小小的練手項目,不過對于目前的我,感覺還是不錯的。 showImg(https://oc1gyfe6q.qnssl.com/17-3-30/43434844-file_1490879850754_14751...
摘要:用來主要前臺的請求,并處理返回相關(guān)的數(shù)據(jù),做后臺服務(wù)。總結(jié)做完這個項目,其中的過程還是挺艱辛的,畢竟都是邊學(xué)邊做,不過最后能完成還是挺開心的,終于有了一個從到的項目過程。雖然只是一個小小的練手項目,不過對于目前的我,感覺還是不錯的。 showImg(https://oc1gyfe6q.qnssl.com/17-3-30/43434844-file_1490879850754_14751...
閱讀 3323·2021-11-25 09:43
閱讀 3008·2021-10-15 09:43
閱讀 1965·2021-09-08 09:36
閱讀 2918·2019-08-30 15:56
閱讀 742·2019-08-30 15:54
閱讀 2684·2019-08-30 15:54
閱讀 2973·2019-08-30 11:26
閱讀 1237·2019-08-29 17:27