首頁 > 軟體

Vue中如何把hash模式改為history模式

2022-07-27 14:00:32

把hash模式改為history模式

如上圖所示非常簡單

只需要在檔案router下的index.js里加上一個mode:'history’即可把hash模式改為history模式.這個時候url上面的#號就不會再存在了,這樣就把url成功把hash模式改成history了

關於路由hash和history模式

hash模式

hash 就是指 url 後的 # 號以及後面的字元,

比如,http://127.0.0.1:5500/test.html#/user,這裡的hash值就是#/user。

hash 值的變化不會導致瀏覽器像伺服器傳送請求

hash 的改變會觸發 hashChange 事件,瀏覽器的前進後退也能對其進行控制

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>hash模式的實現</title>
</head>
<body>
  <button id="myBtn">改變hash的值</button>
  <script>
    const myBtn = document.getElementById('myBtn');
      // 通過 onhashchange 監聽hash值變化
    window.onhashchange = (e) => {
      console.log('老URL',e.oldURL);
      console.log('新URL',e.newURL);
      console.log('hash',location.hash);
    }
  </script>
</body>
</html>

上面是通過 on 來監聽事件,其實也可以用

window.addEventListener("hashchange", funcRef, false);

改變hash的三種方式:

第一種:手動在導航欄中修改

控制檯的輸出

第二種方式:手動點選前進後退按鈕

這裡是點選了後退按鈕,從 #/user 後退到了 #/

第三種方式:通過js程式碼修改

給按鈕增加監聽函數,當點選按鈕時,進行路由改變。

  <script>
    const myBtn = document.getElementById('myBtn');
    window.onhashchange = (e) => {
      console.log('老URL',e.oldURL);
      console.log('新URL',e.newURL);
      console.log('hash',location.hash);
    }
    // 增加監聽函數
    myBtn.addEventListener('click',() => {
      location.href = '#/user';
    })
  </script>

起初,路由位於http://127.0.0.1:5500/test.html#/,

然後點選按鈕

注:Location物件用於表示window上當前連結到的URL資訊。

  • href: 當前window對應的超連結URL, 整個URL;
  • hash: 雜湊值;
  • pathname:存取頁面;

用一個網址來演示location的屬性

//http://127.0.0.1:8001/01-hash.html?a=100&b=20#/aaa/bbb
location.protocal // 'http:'
localtion.hostname // '127.0.0.1'
location.host // '127.0.0.1:8001'
location.port //8001
location.pathname //'01-hash.html'
location.serach // '?a=100&b=20'
location.hash // '#/aaa/bbb'

對於href屬性

history 模式

預設情況下, 路徑的改變使用的URL的hash.

如果使用history模式,在設定路由規則時,加入"mode: ‘history’".

//main.js檔案中
const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

history 模式,每存取一個頁面都要發起網路請求,每個請求都需要伺服器進行路由匹配、資料庫查詢、生成HTML檔案後再傳送響應給瀏覽器,這個過程會消耗伺服器的大量資源,給伺服器的壓力較大。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>history模式的實現</title>
</head>
<body>
  <button id="myBtn">改變hash的值</button>
  <script>
    const myBtn = document.getElementById('myBtn');
    window.addEventListener('DOMContentLoaded',() => {
      //頁面DOM載入完畢後列印出頁面的路徑
      console.log('path: ',location.pathname);
    })
    myBtn.addEventListener('click',() => {
      const state = {name:'user'};
      history.pushState(state, '', 'user');
      console.log('切換路由到了','user');
      console.log('path: ',location.pathname);
    })
  </script>
</body>
</html>

起初路由位於http://127.0.0.1:5500/test.html,

當點選了按鈕之後,路由變成了http://127.0.0.1:5500/user。

history 模式

利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。

history.pushState();         // 新增新的狀態到歷史狀態棧
history.replaceState();      // 用新的狀態代替當前狀態
history.state                // 返回當前狀態物件
  • history.pushState() 在保留現有歷史記錄的同時,將 url 加入到歷史記錄中。
  • history.replaceState() 會將歷史記錄中的當前頁面歷史替換為 url。

由於 history.pushState() 和 history.replaceState() 可以改變 url 同時,不會重新整理頁面,所以在 HTML5 中的 histroy 具備了實現前端路由的能力。

這兩個方法有個共同的特點:當呼叫他們修改瀏覽器歷史記錄棧後,雖然當前 URL 改變了,但瀏覽器不會重新整理頁面,這就為單頁應用前端路由“更新檢視但不重新請求頁面”提供了基礎。

history

在修改 url 後,雖然頁面並不會重新整理,但我們在手動重新整理,或通過 url 直接進入應用的時候, 伺服器端是無法識別這個 url 的,會報 404 問題。

因為我們是單頁應用,只有一個 html 檔案,伺服器端在處理其他路徑的 url 的時候,就會出現404的情況。 所以,如果要應用 history 模式,需要在伺服器端增加一個覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態資源,則應該返回單頁應用的 html 檔案。

popstate

在history模式中與hash模式的hashchange對應的是popState

popstate是在瀏覽器回退前進或者js的 back() go() forward()方法的時候才會觸發。

    //監聽 popstate 事件
    window.onpopstate = (e) => {
      console.log('onpopstate', e.state, location.pathname);
    }

二者對比

1.從相容角度分析。

hash 可以相容到 IE8,history 只能相容到 IE10。

2.從網路請求的角度分析。

使用 hash 模式,地址改變時通過 hashchange 事件,只會讀取雜湊符號後的內容,並不會發起任何網路請求。

history 模式,每存取一個頁面都要發起網路請求,每個請求都需要伺服器進行路由匹配、資料庫查詢、生成HTML檔案後再傳送響應給瀏覽器,這個過程會消耗伺服器的大量資源,給伺服器的壓力較大。

3.伺服器設定角度分析。

hash 不需要伺服器任何設定。

history 進行重新整理頁面時,無法找到url對應的頁面,會出現 404 問題。如果要應用 history 模式,需要在伺服器端增加一個覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態資源,則應該返回單頁應用的 html 檔案。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com