切換語言為:簡體

雜湊路由在 SPA 中的妙用,以提高了應用的效能和使用者體驗。

  • 爱糖宝
  • 2024-07-11
  • 2062
  • 0
  • 0

前言

單頁應用(Single Page Application,簡稱SPA)的設計模式在現代Web開發中變得越來越流行,主要因為它能提供類似桌面應用的使用者體驗。SPA透過動態載入和替換部分網頁內容,而無需重新載入整個頁面,這帶來了快速響應和流暢的互動效果。然而,這種模式對傳統的HTTP協議提出了挑戰,因為HTTP本質上是無狀態的,且伺服器無法主動向客戶端推送內容。因此,SPA需要一些技術來管理狀態並實現頁面的動態更新。

正文

使用Hash Router進行管理

在單頁應用中,一個常見的解決方案是使用“Hash Router”。Hash Router利用URL中的hash(#)部分來區分不同的頁面或檢視。當用戶在瀏覽器位址列中修改URL的hash部分時,瀏覽器會觸發hashchange事件。開發者可以監聽這個事件,並透過非同步請求(如AJAX)從伺服器獲取資料,然後更新DOM以顯示相應的檢視。

有許多小白可能不懂什麼意思

簡單來說,在傳統的多面應用中,每個頁面都有獨特的URL,例如我們從掘金首頁

雜湊路由在 SPA 中的妙用,以提高了應用的效能和使用者體驗。 

此時的URL為https://juejin.cn/,而如果我們進入某一篇文章時,整個頁面會重新載入並重新整理

雜湊路由在 SPA 中的妙用,以提高了應用的效能和使用者體驗。

URL也會隨之改變,使得頁面會重新載入

URL的改變意味著瀏覽器需要重新向對應伺服器傳送請求,十分耗費伺服器資源

但是在單頁面應用當中,頁面的主要內容不會重新載入,而是透過JavaScript動態地替換部分內容,從而提供了更快的響應速度和更流暢的使用者體驗。

這個雜湊路由就是一個錨點

舉個例子!

在某篇文章中,其右邊的目錄就運用了雜湊路由

雜湊路由在 SPA 中的妙用,以提高了應用的效能和使用者體驗。

例如我們點選它的結語,頁面就會跳到這個部分,

雜湊路由在 SPA 中的妙用,以提高了應用的效能和使用者體驗。

並且URL改變為

雜湊路由在 SPA 中的妙用,以提高了應用的效能和使用者體驗。

其URL內的Hash欄位則會修改,Hash欄位就是URL中帶#後的內容

修改後,頁面並不載入,而是跳轉到定義的錨點,這個錨點就是雜湊路由,而在這個URL中,它的結語的雜湊路由為heading-5

現在你明白什麼是雜湊路由(Hash Router)了嗎

我們現在就來探究一下,這樣一個錨點是如何實現的

先設定三個導航欄
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>手寫Hash Router</title>
</head>
<body>
    <nav id="nav">
        <ul>
            <li><a href="#/page1">page1</a></li>
            <li><a href="#/page2">page2</a></li>
            <li><a href="#/page3">page3</a></li>
    </nav>
    <div id="container"></div>
</body>
</html>

我們使用<a>標籤來分別指向三個頁面的URL,#就代表著URL的雜湊欄位,點選這三個標籤就會分別跳轉這三個錨點。

還定義了一個container,用來放顯示的介面,就像Vue中的<router-view>

接下來我們透過JS來實現——錨點時空跳躍

也就是說,當我們跳轉至#/page1時,page1就要放進container中

我們跳轉至#/page1時,page1就要放進container中

開始動手!

我們先定義一個實現路由類:

class HashRouter{}

再寫一個建構函式,定義一個變數routes來儲存路由規則,再新增一個事件監聽,監聽hashchange事件,一旦hash值改變,就呼叫load方法。

 constructor() {
        this.routes = {}; // 建立一個物件來儲存路由規則
        window.addEventListener('hashchange', this.load.bind(this), false); // 當URL的hash部分發生變化時,呼叫load方法
    }

我們再寫兩個函式,將各頁面匯入進HTML的方法使用routes物件透過陣列繫結,也就是註冊路由規則

 register (hash, callback = function() {}) {
        this.routes[hash] = callback; // 註冊路由規則,將hash和對應的回撥函式儲存在routes物件中
    }
    registerIndex(callback = function() {}) {
        this.routes['index'] = callback; // 註冊預設路由,當hash為空時使用
    }

接下來我們來寫load方法,

先從location.hash獲取當前URL的雜湊部分。由於雜湊總是以#開始,所以使用slice(1)來去除這個字元,得到實際的雜湊值字串。

再根據hash的值,load方法會從this.routes物件中查詢對應的處理器。如果hash為空,意味著URL中沒有特定的雜湊值,這時會使用預設的index處理器,即透過registerIndex方法註冊的回撥函式。如果hash有值,它會嘗試作為鍵在routes物件中查詢對應的處理器。

簡單來說,如果URL中有hash欄位則呼叫該頁面的方法使該頁面展示,如果沒有就展示首頁

load() {
        let hash = location.hash.slice(1); // 去掉hash字首'#",獲取當前hash值
        let handler;
        if(!hash) {
            // 如果hash為空,則使用預設路由
            handler = this.routes['index'];
        } else {
            // 否則根據hash值找到對應的handler
            handler = this.routes[hash];
        }
        handler && handler.call(this); // 執行找到的handler,如果沒有找到則不執行任何操作
    }

最後我們建立一個例項物件,再獲取container元素

let router = new HashRouter(); // 建立一個HashRouter例項
let container = document.getElementById('container'); // 獲取頁面上的容器元素

我們將三個頁面事件和首頁與例項物件內的routes物件進行路由規則註冊

// 註冊不同的路由規則
router.registerIndex(() => container.innerHTML = '我是首頁');
router.register('/page1', () => container.innerHTML = '我是Page1');
router.register('/page2', () => container.innerHTML = '我是Page2');
router.register('/page3', () => container.innerHTML = '我是Page3');

最後載入路由規則

router.load(); // 載入當前的路由規則

於是我們的手寫雜湊路由就完成了

雜湊路由在 SPA 中的妙用,以提高了應用的效能和使用者體驗。

點選page1 雜湊路由在 SPA 中的妙用,以提高了應用的效能和使用者體驗。

完整js程式碼

 
class HashRouter{
    constructor() {
        this.routes = {}; // 建立一個物件來儲存路由規則
        window.addEventListener('hashchange', this.load.bind(this), false); // 當URL的hash部分發生變化時,呼叫load方法
    }
    register (hash, callback = function() {}) {
        this.routes[hash] = callback; // 註冊路由規則,將hash和對應的回撥函式儲存在routes物件中
    }
    registerIndex(callback = function() {}) {
        this.routes['index'] = callback; // 註冊預設路由,當hash為空時使用
    }
    load() {
        let hash = location.hash.slice(1); // 去掉hash字首'#",獲取當前hash值
        let handler;
        if(!hash) {
            // 如果hash為空,則使用預設路由
            handler = this.routes['index'];
        } else {
            // 否則根據hash值找到對應的handler
            handler = this.routes[hash];
        }
        handler && handler.call(this); // 執行找到的handler,如果沒有找到則不執行任何操作
    }
}

let router = new HashRouter(); // 建立一個HashRouter例項
let container = document.getElementById('container'); // 獲取頁面上的容器元素

// 註冊不同的路由規則
router.registerIndex(() => container.innerHTML = '我是首頁');
router.register('/page1', () => container.innerHTML = '我是Page1');
router.register('/page2', () => container.innerHTML = '我是Page2');
router.register('/page3', () => container.innerHTML = '我是Page3');

router.load(); // 載入當前的路由規則

總結

雜湊路由是一種實用的技術,它使得SPA能夠在不重新載入整個頁面的情況下實現頁面內容的動態更新,從而提高了應用的效能和使用者體驗。

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.