1. 程式人生 > 程式設計 >Vue-router中hash模式與history模式的區別詳解

Vue-router中hash模式與history模式的區別詳解

VUE路由的hash模式與history模式的區別,這個也是面試常問的問題,這個題其實就是考驗你的開發經驗是否屬實。

小白回答:hash模式url帶#號,history模式不帶#號。

大牛解答:

形式上:hash模式url裡面永遠帶著#號,開發當中預設使用這個模式。如果使用者考慮url的規範那麼就需要使用history模式,因為history模式沒有#號,是個正常的url,適合推廣宣傳;

功能上:比如我們在開發app的時候有分享頁面,那麼這個分享出去的頁面就是用vue或是react做的,咱們把這個頁面分享到第三方的app裡,有的app裡面url是不允許帶有#號的,所以要將#號去除那麼就要使用history模式,但是使用history模式還有一個問題就是,在訪問二級頁面的時候,做重新整理操作,會出現404錯誤,那麼就需要和後端人配合,讓他配置一下apache或是nginx的url重定向,重定向到你的首頁路由上就ok了

正題開始

為了達到改變檢視的同時不會向後端發出請求這一目的,瀏覽器當前提供了以下兩種支援:

hash模式:即位址列 URL 中的 # 符號

比如這個 URL:http://www.abc.com/#/hello, hash 的值為 #/hello

它的特點在於:hash 雖然出現在 URL 中,但不會被包括在 HTTP 請求中,對後端完全沒有影響,因此改變 hash 不會重新載入頁面。

history模式:利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定瀏覽器支援)

這兩個方法應用於瀏覽器的歷史記錄棧,在當前已有的 back()、forward()、go() 方法的基礎之上,這兩個方法提供了對歷史記錄進行修改的功能。當這兩個方法執行修改時,只能改變當前位址列的 URL,但瀏覽器不會向後端傳送請求,也不會觸發popstate事件的執行

因此可以說,hash 模式和 history 模式都屬於瀏覽器自身的特性,Vue-Router 只是利用了這兩個特性(通過呼叫瀏覽器提供的介面)來實現前端路由.

vue中的router有兩種模式:hash模式(預設)、history模式(需配置mode: 'history')

Vue-router中hash模式與history模式的區別詳解

vue中的hash模式

即位址列 URL 中的 # 符號,這個#就是hash符號,中文名雜湊符或錨點

比如這個 URL:http://www.baidu.com/#/home,hash 的值為 #/home

它的特點在於:hash 雖然出現在 URL 中,但不會被包括在 HTTP 請求中,對後端完全沒有影響,因此改變 hash 不會重新載入頁面。

Vue-router中hash模式與history模式的區別詳解

路由的雜湊模式其實是利用了window.onhashchange事件,也就是說你的url中的雜湊值(#後面的值)如果有變化,就會自動呼叫hashchange的監聽事件,在hashchange的監聽事件內可以得到改變後的url,這樣能夠找到對應頁面進行載入

window.addEventListener('hashchange',() => {
  // 把改變後的url位址列的url賦值給data的響應式資料current,呼叫router-view去載入對應的頁面
  this.data.current = window.location.hash.substr(1)
})

vue中history模式

HTML5 History Interface 中新增的兩個神器 pushState() 和 replaceState() 方法(需要特定瀏覽器支援),用來完成 URL 跳轉而無須重新載入頁面,不過這種模式還需要後臺配置支援。因為我們的應用是個單頁客戶端應用,如果後臺沒有正確的配置,就需要前端自己配置404頁面。

Vue-router中hash模式與history模式的區別詳解

pushState() 和 replaceState() 這兩個神器的作用就是可以將url替換並且不重新整理頁面,好比掛羊頭賣狗肉,http並沒有去請求伺服器該路徑下的資源,一旦重新整理就會暴露這個實際不存在的“羊頭”,顯示404(因為瀏覽器一旦重新整理,就是去真正請求伺服器資源)

那麼如何去解決history模式下重新整理報404的弊端呢,這就需要伺服器端做點手腳,將不存在的路徑請求重定向到入口檔案(index.html),前後端聯手,齊心協力做好“掛羊頭賣狗肉”的完美特效

pushState方法、replaceState方法,只能導致history物件發生變化,從而改變當前位址列的 URL,但瀏覽器不會向後端傳送請求,也不會觸發popstate事件的執行

popstate事件的執行是在點選瀏覽器的前進後退按鈕的時候,才會被觸發

window.addEventListener('popstate',() => {
 this.data.current = window.location.pathname
})

使用場景

一般場景下,hash 和 history 都可以,除非你更在意顏值,# 符號夾雜在 URL 裡看起來確實有些不太美麗。

如果不想要很醜的 hash,我們可以用路由的 history 模式,這種模式充分利用 history.pushState API 來完成URL 跳轉而無須重新載入頁面。 Vue-router 另外,根據 Mozilla Develop Network 的介紹,呼叫 history.pushState() 相比於直接修改 hash,存在以下優勢:

pushState() 設定的新 URL 可以是與當前 URL 同源的任意 URL;而 hash 只可修改 # 後面的部分,因此只能設定與當前 URL 同文檔的 URL

pushState() 設定的新 URL 可以與當前 URL 一模一樣,這樣也會把記錄新增到棧中;而 hash 設定的新值必須與原來不一樣才會觸發動作將記錄新增到棧中

pushState() 通過 stateObject 引數可以新增任意型別的資料到記錄中;而 hash 只可新增短字串

pushState() 可額外設定 title 屬性供後續使用

總結

傳統的路由指的是:當用戶訪問一個url時,對應的伺服器會接收這個請求,然後解析url中的路徑,從而執行對應的處理邏輯。這樣就完成了一次路由分發

而前端路由是不涉及伺服器的,是前端利用hash或者HTML5的history API來實現的,一般用於不同內容的展示和切換

到此這篇關於Vue-router中hash模式與history模式的區別詳解的文章就介紹到這了,更多相關Vue-router中hash模式與history模式區別內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!