hash前端路由,無(wú)刷新
history 會(huì)去請(qǐng)求接口
vue-router提供兩種模式的原因:
vue 是漸進(jìn)式前端開(kāi)發(fā)框架,為了實(shí)現(xiàn) SPA ,需要引入前端路由系統(tǒng)(vue-router)。前端路由的核心是:改變視圖的同時(shí)不會(huì)向后端發(fā)出請(qǐng)求。
為了達(dá)到這一目的,瀏覽器提供了 hash 和 history 兩種模式。
- hash :hash 雖然出現(xiàn)在 URL 中,但不會(huì)被包含在 http 請(qǐng)求中,對(duì)后端完全沒(méi)有影響,因此改變 hash 不會(huì)重新加載頁(yè)面。
- history :history 利用了 html5 history interface 中新增的 pushState() 和 replaceState() 方法。這兩個(gè)方法應(yīng)用于瀏覽器記錄棧,在當(dāng)前已有的 back、forward、go 基礎(chǔ)之上,它們提供了對(duì)歷史記錄修改的功能。只是當(dāng)它們執(zhí)行修改時(shí),雖然改變了當(dāng)前的 URL ,但瀏覽器不會(huì)立即向后端發(fā)送請(qǐng)求。
因此可以說(shuō), hash 模式和 history 模式都屬于瀏覽器自身的屬性,vue-router 只是利用了這兩個(gè)特性(通過(guò)調(diào)用瀏覽器提供的接口)來(lái)實(shí)現(xiàn)路由。
實(shí)現(xiàn)的原理:
- hash 模式的原理是 onhashchange 事件,可以在 window 對(duì)象上監(jiān)聽(tīng)這個(gè)事件。
- history :hashchange 只能改變 # 后面的代碼片段,history api (pushState、replaceState、go、back、forward) 則給了前端完全的自由,通過(guò)在window對(duì)象上監(jiān)聽(tīng)popState()事件。
pushState()、replaceState() 方法接收三個(gè)參數(shù):stateObj、title、url。
// 設(shè)置狀態(tài)
history.pushState({color: "red"}, "red", "red");
// 監(jiān)聽(tīng)狀態(tài)
window.onpopstate = function(event){
console.log(event.state);
if(event.state && event.state.color === "red"){
document.body.style.color = "red";
}
}
// 改變狀態(tài)
history.back();
history.forward();復(fù)制代碼
應(yīng)用場(chǎng)景:
通過(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è)面滾動(dòng)條的位置、閱讀進(jìn)度、組件的開(kāi)關(guān)等。
調(diào)用 history.pushState() 比使用 hash 存在的優(yōu)勢(shì):
- pushState 設(shè)置的 url 可以是同源下的任意 url ;而 hash 只能修改 # 后面的部分,因此只能設(shè)置當(dāng)前 url 同文檔的 url
- pushState 設(shè)置的新的 url 可以與當(dāng)前 url 一樣,這樣也會(huì)把記錄添加到棧中;hash 設(shè)置的新值不能與原來(lái)的一樣,一樣的值不會(huì)觸發(fā)動(dòng)作將記錄添加到棧中
- pushState 通過(guò) stateObject 參數(shù)可以將任何數(shù)據(jù)類(lèi)型添加到記錄中;hash 只能添加短字符串
- pushState 可以設(shè)置額外的 title 屬性供后續(xù)使用
劣勢(shì):
- history 在刷新頁(yè)面時(shí),如果服務(wù)器中沒(méi)有相應(yīng)的響應(yīng)或資源,就會(huì)出現(xiàn)404。因此,如果 URL 匹配不到任何靜態(tài)資源,則應(yīng)該返回同一個(gè) index.html 頁(yè)面,這個(gè)頁(yè)面就是你 app 依賴(lài)的頁(yè)面
- hash 模式下,僅 # 之前的內(nèi)容包含在 http 請(qǐng)求中,對(duì)后端來(lái)說(shuō),即使沒(méi)有對(duì)路由做到全面覆蓋,也不會(huì)報(bào) 404
參考:https://blog.csdn.net/majunjie2017/article/details/78507551