vue-router路由模式詳解(小結(jié))
一、路由模式解析
要講vue-router的路由模式,首先要了解的一點(diǎn)就是路由是由多個(gè)URL組成的,使用不同的URL可以相應(yīng)的導(dǎo)航到不同的位置。
如果有進(jìn)行過(guò)服務(wù)器開發(fā)或者對(duì)http協(xié)議有所了解就會(huì)知道,瀏覽器中對(duì)頁(yè)面的訪問(wèn)是無(wú)狀態(tài)的,所以我們?cè)谇袚Q不同的頁(yè)面時(shí)都會(huì)重新進(jìn)行請(qǐng)求。而實(shí)際使用vue和vue-router開發(fā)就會(huì)明白,在切換頁(yè)面時(shí)是沒(méi)有重新進(jìn)行請(qǐng)求的,使用起來(lái)就好像頁(yè)面是有狀態(tài)的,這是什么原因呢。
這其實(shí)是借助了瀏覽器的History API來(lái)實(shí)現(xiàn)的,這樣可以使得頁(yè)面跳轉(zhuǎn)而不刷新,頁(yè)面的狀態(tài)就被維持在瀏覽器中了。
vue-router中默認(rèn)使用的是hash模式,也就是會(huì)出現(xiàn)如下的URL:
,URL中帶有#號(hào)
我們可以用如下代碼修改成history模式:
import Vue from 'vue'
import Router from 'vue-router'
import Main from '@/components/Main'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/',
component: Main
}
]
})
這樣子URL中的#號(hào)就被去除了。
實(shí)際上存在三種模式:
Hash: 使用URL的hash值來(lái)作為路由。支持所有瀏覽器。
History: 以來(lái)HTML5 History API 和服務(wù)器配置。參考官網(wǎng)中HTML5 History模式
Abstract: 支持所有javascript運(yùn)行模式。如果發(fā)現(xiàn)沒(méi)有瀏覽器的API,路由會(huì)自動(dòng)強(qiáng)制進(jìn)入這個(gè)模式。
二、兩種模式的區(qū)別
1、hash模式
hash模式背后的原理是onhashchange事件,可以在window對(duì)象上監(jiān)聽(tīng)這個(gè)事件:
window.onhashchange = function(event){
console.log(event.oldURL, event.newURL);
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),盡管瀏覽器沒(méi)有請(qǐng)求服務(wù)器,但是頁(yè)面狀態(tài)和url一一關(guān)聯(lián)起來(lái),后來(lái)人們給它起了一個(gè)霸氣的名字叫前端路由,成為了單頁(yè)應(yīng)用標(biāo)配。
我們寫個(gè)簡(jiǎn)單的方法來(lái)測(cè)試一下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div>測(cè)試一下</div>
<script type="text/javascript">
window.onhashchange = function(event){
console.log(event.oldURL,event.newURL)
let hash = location.hash.slice(1);
document.body.style.color = hash;
}
</script>
</body>
</html>


并且通過(guò)瀏覽器的前進(jìn)、后退頁(yè)面均可以變化。
網(wǎng)易云音樂(lè),百度網(wǎng)盤就采用了hash路由,看起來(lái)就是這個(gè)樣子:
http://music.163.com/#/friend
https://pan.baidu.com/disk/home#list/vmode=list
2、history路由
隨著history api的到來(lái),前端路由開始進(jìn)化了,前面的hashchange,你只能改變#后面的url片段,而history api則給了前端完全的自由
history api可以分為兩大部分:切換和修改
(1)切換歷史狀態(tài)
包括back、forward、go三個(gè)方法,對(duì)應(yīng)瀏覽器的前進(jìn),后退,跳轉(zhuǎn)操作,有同學(xué)說(shuō)了,(谷歌)瀏覽器只有前進(jìn)和后退,沒(méi)有跳轉(zhuǎn),嗯,在前進(jìn)后退上長(zhǎng)按鼠標(biāo),會(huì)出來(lái)所有當(dāng)前窗口的歷史記錄,從而可以跳轉(zhuǎn)(也許叫跳更合適):
history.go(-2);//后退兩次 history.go(2);//前進(jìn)兩次 history.back(); //后退 hsitory.forward(); //前進(jìn)
(2)修改歷史狀態(tài)
包括了pushState、replaceState兩個(gè)方法,這兩個(gè)方法接收三個(gè)參數(shù):stateObj,title,url
history.pushState({color:'red'}, 'red', 'red')
window.onpopstate = function(event){
console.log(event.state)
if(event.state && event.state.color === 'red'){
document.body.style.color = 'red';
}
}
history.back();
history.forward();
通過(guò)pushstate把頁(yè)面的狀態(tài)保存在state對(duì)象中,當(dāng)頁(yè)面的url再變回這個(gè)url時(shí),可以通過(guò)event.state取到這個(gè)state對(duì)象,從而可以對(duì)頁(yè)面狀態(tài)進(jìn)行還原,這里的頁(yè)面狀態(tài)就是頁(yè)面字體顏色,其實(shí)滾動(dòng)條的位置,閱讀進(jìn)度,組件的開關(guān)的這些頁(yè)面狀態(tài)都可以存儲(chǔ)到state的里面。
通過(guò)history api,我們丟掉了丑陋的#,但是它也有個(gè)毛?。?/p>
不怕前進(jìn),不怕后退,就怕刷新,f5,(如果后端沒(méi)有準(zhǔn)備的話),因?yàn)樗⑿率菍?shí)實(shí)在在地去請(qǐng)求服務(wù)器的。
在hash模式下,前端路由修改的是#中的信息,而瀏覽器請(qǐng)求時(shí)是不帶它玩的,所以沒(méi)有問(wèn)題。但是在history下,你可以自由的修改path,當(dāng)刷新時(shí),如果服務(wù)器中沒(méi)有相應(yīng)的響應(yīng)或者資源,會(huì)分分鐘刷出一個(gè)404來(lái)。
(3)popstate實(shí)現(xiàn)history路由攔截,監(jiān)聽(tīng)頁(yè)面返回事件
當(dāng)活動(dòng)歷史記錄條目更改時(shí),將觸發(fā)popstate事件。
1、如果被激活的歷史記錄條目是通過(guò)對(duì) history.pushState() 的調(diào)用創(chuàng)建的,或者受到對(duì) history.replaceState() 的調(diào)用的影響,popstate事件的state屬性包含歷史條目的狀態(tài)對(duì)象的副本。
2、需要注意的是調(diào)用 history.pushState() 或 history.replaceState() 用來(lái)在瀏覽歷史中添加或修改記錄,不會(huì)觸發(fā)popstate事件;
只有在做出瀏覽器動(dòng)作時(shí),才會(huì)觸發(fā)該事件,如用戶點(diǎn)擊瀏覽器的回退按鈕(或者在Javascript代碼中調(diào)用history.back())
我們測(cè)試一下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div>測(cè)試一下</div>
<script type="text/javascript">
if (window.history && window.history.pushState) {
window.onpopstate = function(event) {
console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
//window.history.go(1)
//window.history.back()
};
//window.addEventListener("popstate", function(e) {
// window.location = 'http://www.baidu.com';
//}, false);
!function() {
var state = {
title: "title",
url: "#"
};
window.history.pushState(state, "title", "#");
}();
}
</script>
</body>
</html>
刷新時(shí)不打印,刷新多次,再后退,每次都有,直到為null

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vite+vue3項(xiàng)目初始化搭建的實(shí)現(xiàn)步驟
本文主要介紹了vite+vue3項(xiàng)目初始化搭建的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07
詳解為什么Vue中不要用index作為key(diff算法)
這篇文章主要介紹了詳解為什么Vue中不要用index作為key(diff算法),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
vue進(jìn)度條組件實(shí)現(xiàn)代碼(可拖拽可點(diǎn)擊)
在日常開發(fā)中隨著需求的個(gè)性化,邏輯的復(fù)雜化,自定義組件也變得越來(lái)越常見(jiàn),這篇文章主要給大家介紹了關(guān)于vue進(jìn)度條組件實(shí)現(xiàn)(可拖拽可點(diǎn)擊)的相關(guān)資料,需要的朋友可以參考下2023-12-12
使用vue3+TS實(shí)現(xiàn)簡(jiǎn)易組件庫(kù)的全過(guò)程
當(dāng)市面上主流的組件庫(kù)不能滿足我們業(yè)務(wù)需求的時(shí)候,那么我們就有必要開發(fā)一套屬于自己團(tuán)隊(duì)的組件庫(kù),下面這篇文章主要給大家介紹了如何使用vue3+TS實(shí)現(xiàn)簡(jiǎn)易組件庫(kù)的相關(guān)資料,需要的朋友可以參考下2022-03-03
vant steps流程圖的圖標(biāo)使用slot自定義方式
這篇文章主要介紹了vant steps流程圖的圖標(biāo)使用slot自定義方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
Vue生命周期activated之返回上一頁(yè)不重新請(qǐng)求數(shù)據(jù)操作
這篇文章主要介紹了Vue生命周期activated之返回上一頁(yè)不重新請(qǐng)求數(shù)據(jù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07
使用vue實(shí)現(xiàn)一個(gè)電子簽名組件的示例代碼
這篇文章主要介紹了使用vue實(shí)現(xiàn)一個(gè)電子簽名組件的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01
vue里的axios如何獲取本地json數(shù)據(jù)
這篇文章主要介紹了vue里的axios如何獲取本地json數(shù)據(jù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
Vue3?計(jì)算屬性computed的實(shí)現(xiàn)原理
這篇文章主要介紹了Vue3?計(jì)算屬性computed的實(shí)現(xiàn)原理,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-08-08

