前端頁(yè)面三種路由實(shí)現(xiàn)方式以及區(qū)別

1.傳統(tǒng)路由實(shí)現(xiàn)。

window.location.href = 'https://baidu.com' 跳轉(zhuǎn)。刷新頁(yè)面。 history.back()回退。 整個(gè)頁(yè)面重新加載,瀏覽器歷史可以顯示每一個(gè)地址。考慮到安全性但是JS代碼中是無(wú)法操作的。

2.Hash路由方式。

window.href.href = '#hash' localhost:9000#test。并不刷新頁(yè)面。 #后跟的就是頁(yè)面Hash,同樣hash的改變也會(huì)推進(jìn)瀏覽器歷史記錄中。 支持后退前進(jìn)。

window.onhashchange = function () {

? ? console.log('current Hash:',window.location.hash)

}

3.H5 Router。

history.pushState(state, title[, url]) 推進(jìn)路由。增加歷史盞中的一條。 history.replaceState(state,title[, url]) 替換路由。在歷史記錄中替換當(dāng)前記錄。

可以改變網(wǎng)址(存在跨域限制)而不刷新頁(yè)面,這個(gè)強(qiáng)大的特性后來(lái)用到了單頁(yè)面應(yīng)用如:vue-router,react-router-dom中。

僅改變網(wǎng)址,網(wǎng)頁(yè)不會(huì)真的跳轉(zhuǎn),也不會(huì)獲取到新的內(nèi)容,本質(zhì)上網(wǎng)頁(yè)還停留在原頁(yè)面。

狀態(tài)對(duì)象:傳給目標(biāo)路由的信息,可為空

頁(yè)面標(biāo)題:目前所有瀏覽器都不支持,填空字符串即可

可選url:目標(biāo)url,不會(huì)檢查url是否存在,且不能跨域。如不傳該項(xiàng),即給當(dāng)前url添加data

popstate事件會(huì)在點(diǎn)擊后退、前進(jìn)按鈕(或調(diào)用history.back()、history.forward()、history.go()方法)時(shí)觸發(fā)。前提是不能真的發(fā)生了頁(yè)面跳轉(zhuǎn),而是在由history.pushState()或者h(yuǎn)istory.replaceState()形成的歷史節(jié)點(diǎn)中前進(jìn)后退

注意:用history.pushState()或者h(yuǎn)istory.replaceState()不會(huì)觸發(fā)popstate事件。

history.state

當(dāng)前URL下對(duì)應(yīng)的狀態(tài)信息。如果當(dāng)前URL不是通過(guò)pushState或者replaceState產(chǎn)生的,那么history.state是null。history.state可以保存當(dāng)前頁(yè)面的信息,通過(guò)pushState或者replaceState傳遞onpopstate中改變時(shí)候獲得(history.state也可以獲取)。

history.pushState(state, title, url)

state:與要跳轉(zhuǎn)到的URL對(duì)應(yīng)的狀態(tài)信息。

title:不知道干啥用,傳空字符串就行了。

url:要跳轉(zhuǎn)到的URL地址,不能跨域。

將當(dāng)前URL和history.state加入到history中,并用新的state和URL替換當(dāng)前。不會(huì)造成頁(yè)面刷新。

history.replaceState

state:與要跳轉(zhuǎn)到的URL對(duì)應(yīng)的狀態(tài)信息。

title:不知道干啥用,傳空字符串就行了。

url:要跳轉(zhuǎn)到的URL地址,不能跨域。

用新的state和URL替換當(dāng)前。不會(huì)造成頁(yè)面刷新。

window.onpopstate

history.go和history.back(包括用戶按瀏覽器歷史前進(jìn)后退按鈕)觸發(fā),并且頁(yè)面無(wú)刷的時(shí)候(由于使用pushState修改了history)會(huì)觸發(fā)popstate事件,事件發(fā)生時(shí)瀏覽器會(huì)從history中取出URL和對(duì)應(yīng)的state對(duì)象替換當(dāng)前的URL和history.state。通過(guò)event.state也可以獲取history.state。

window.onpopstate = function(event) {

? console.log(event.state); // 當(dāng)前頁(yè)面相關(guān)的history路由信息

? console.log(window.history.state;); // 當(dāng)前頁(yè)面相關(guān)的history路由信息

? console.log(window.location.hash) // hash路徑

? console.log(window.location.pathname) // 絕對(duì)路徑

? console.log(window.location.href) // 全部路徑

};

引入Vue中兩種路由模式的區(qū)別。

Hash模式

hash模式背后的原理是onhashchange事件,可以在window對(duì)象上監(jiān)聽這個(gè)事件:

window.onhashchange = function(event){

? ? // 打印舊的url和新的url

? ? console.log(event.oldURL, event.newURL);

? ? // 相當(dāng)與跳轉(zhuǎn)頁(yè)面的時(shí)候通過(guò)hash區(qū)別頁(yè)面以及傳遞參數(shù)

? ? let hash = location.hash.slice(1);

? ? document.body.style.color = hash;

}

上面的代碼可以通過(guò)改變hash來(lái)改變頁(yè)面字體顏色,雖然沒(méi)什么用,但是一定程度上說(shuō)明了原理。

更關(guān)鍵的一點(diǎn)是,因?yàn)閔ash發(fā)生變化的url都會(huì)被瀏覽器記錄下來(lái),從而你會(huì)發(fā)現(xiàn)瀏覽器的前進(jìn)后退都可以用了,同時(shí)點(diǎn)擊后退時(shí),頁(yè)面字體顏色也會(huì)發(fā)生變化。這樣一來(lái),瀏覽器不會(huì)發(fā)起請(qǐng)求,但是頁(yè)面狀態(tài)和url關(guān)聯(lián)了起來(lái),url改變頁(yè)面可以根據(jù)url進(jìn)行相應(yīng)邏輯變化。這就是hash路由。

History模式

history api,H5的history api給了前端路由充分的自由。相對(duì)于hash路由來(lái)講前端只能控制#后的url地址,而history api允許在同源策略下進(jìn)行任意的自由路由設(shè)置而不刷新頁(yè)面。

需要額外注意:

history api可以分為兩大部分,切換和修改,參考MDN,切換歷史狀態(tài)包括back、forward、go 三個(gè)方法,對(duì)應(yīng)瀏覽器的前進(jìn),后退,跳轉(zhuǎn)操作:

history.go(-2);//后退兩次

history.go(2);//前進(jìn)兩次

history.back(); //后退

hsitory.forward(); //前進(jìn)

修改歷史狀態(tài)包括了pushState,replaceState

兩個(gè)方法,這兩個(gè)方法接收三個(gè)參數(shù):stateObj,title,url

history.pushState({color:'red'}, 'red', 'red')

history.back();

setTimeout(function(){

? ? history.forward();

},0)

window.onpopstate = function(event){

? ? console.log(event.state)

? ? if(event.state && event.state.color === 'red'){

? ? ? ? ? document.body.style.color = 'red';

? ? ? }

}

history模式配置問(wèn)題

vue-router官方文檔:不過(guò)這種模式要玩好,還需要后臺(tái)配置支持。因?yàn)槲覀兊膽?yīng)用是個(gè)單頁(yè)客戶端應(yīng)用,如果后臺(tái)沒(méi)有正確的配置,當(dāng)用戶在瀏覽器直接訪問(wèn)?http://oursite.com/user/id?就會(huì)返回 404,這就不好看了。

只配置前端的情況 首先,我們將mode設(shè)置為history,但不配置后端。然后,假如我們的路由是長(zhǎng)這個(gè)樣子的:

const routes = [

? ? {path: '/home', component: Home},

? ? {path: '/', redirect: '/home'}

];

我們用nginx部署項(xiàng)目,然后在地址欄輸入?http://localhost:8080?(這里配置的端口是8080),你會(huì)發(fā)現(xiàn)地址欄之后會(huì)變?yōu)?a target="_blank">http://localhost:8080/home,?并且看起來(lái)一切正常,似乎路由也可以正常切換而不會(huì)發(fā)生其他問(wèn)題(實(shí)際上會(huì)發(fā)生問(wèn)題,后面會(huì)進(jìn)行討論)。看起來(lái)好像不需要按官網(wǎng)告訴我們的那樣配置后端也能實(shí)現(xiàn)history模式,但如果你直接在地址欄輸入http://localhost:8080/home?,你會(huì)發(fā)現(xiàn)你獲得了一個(gè)404頁(yè)面。

那么http://localhost:8080?為什么可以(部分)正常顯示呢?道理其實(shí)很簡(jiǎn)單,你訪問(wèn)?http://localhost:8080時(shí), 靜態(tài)服務(wù)器(這里是nginx)會(huì)默認(rèn)去目標(biāo)目錄(這里為location中root所指定的目錄)下尋找index.html(這是nginx在端口后沒(méi)有額外路徑時(shí)的默認(rèn)行為),目標(biāo)目錄下有這個(gè)文件嗎?有!然后靜態(tài)服務(wù)器返回給你這個(gè)文件,配合vue-router進(jìn)行轉(zhuǎn)發(fā),自然可以(部分)正常顯示。 但如果直接訪問(wèn)http://localhost:8080/home,?靜態(tài)服務(wù)器會(huì)去目標(biāo)目錄下尋找home文件,目標(biāo)目錄下有這個(gè)文件嗎?沒(méi)有!所以自然就404了。

配置后端

為了達(dá)到直接訪問(wèn)http://localhost:8080/home?也可以成功的目的,我們需要對(duì)后端(這里即nginx)進(jìn)行一些配置。

首先想想,要怎樣才能達(dá)到這個(gè)目的呢?

在傳統(tǒng)的hash模式中?http://localhost:8080#home?,即使不需要配置,靜態(tài)服務(wù)器始終會(huì)去尋找index.html并返回給我們,然后vue-router會(huì)獲取#后面的字符作為參數(shù),對(duì)前端頁(yè)面進(jìn)行變換。

類比一下,在history模式中,我們所想要的情況就是:輸入http://localhost:8080/home, 但最終返回的也是index.html,然后vue-router會(huì)獲取home作為參數(shù),對(duì)前端頁(yè)面進(jìn)行變換。那么在nginx中,誰(shuí)能做到這件事呢?答案就是try_files。

關(guān)于nginx配置以及history模式可能遇到的問(wèn)題可以參考這篇文章Vue Router history模式的配置方法及其原理

Vue對(duì)比兩種模式

??????已經(jīng)有 hash 模式了,而且 hash 能兼容到IE8, history 只能兼容到 IE10,為什么還要搞個(gè) history 呢?

首先,hash 本來(lái)是拿來(lái)做頁(yè)面定位的,如果拿來(lái)做路由的話,原來(lái)的錨點(diǎn)功能就不能用了。其次,hash 的傳參是基于 url 的,如果要傳遞復(fù)雜的數(shù)據(jù),會(huì)有體積的限制,而 history 模式不僅可以在url里放參數(shù),還可以將數(shù)據(jù)存放在一個(gè)特定的對(duì)象中。 最重要的一點(diǎn):

如果不想要很丑的 hash,我們可以用路由的 history 模式 —— 引用自 vueRouter文檔

轉(zhuǎn)載自:https://github.com/19Qingfeng/Router-way

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,690評(píng)論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,019評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評(píng)論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,188評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,438評(píng)論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,667評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,845評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,384評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容