使用 Blazor 路由器元件,控制您的應用程式瀏覽

已完成

Blazor 的路由系統提供彈性的選項,可用來確保使用者要求抵達了可相應處理的元件,並傳回使用者所需的資訊。

假設您正在建置披薩外送公司的網站。 您想要設定網站,將對披薩詳細資料和自選配料詳細資料的要求,交由相同的元件處理。 您完成了此階段,但測試顯示在要求配料時收到錯誤訊息。 您必須修正此問題。

在此,您將學習如何在 Blazor 中,使用 @page 指示詞設定路由。

注意

本單元中的程式碼區塊是說明範例。 您會在下一個單元中撰寫自己的程式碼。

使用路由範本

當使用者從您的 Web 應用程式要求頁面時,他們可以透過 URI 中的資訊,指定所要檢視的內容。 例如:

http://www.contoso.com/pizzas/margherita?extratopping=pineapple

此 URI 會在通訊協定和網站位址之後,指出使用者想要了解瑪格莉特披薩。 問號之後的查詢字串,顯示他們想要加點鳳梨配料。 在 Blazor 中,您會使用路由來確保每個要求都會傳送至能以最佳方式回應的元件。 您也可以使用路由確保元件具備能夠顯示使用者所需的所有資訊。 在此案例中,您可以將要求傳送至 Pizzas 元件,並希望該元件能夠顯示瑪格莉特披薩及所有有關於加上鳳梨配料的資訊。

Blazor 會使用 Router 的特殊元件路由要求。 該元件會在 App.razor 中設定,如下所示:

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <p>Sorry, we haven't found any pizzas here.</p>
    </NotFound>
</Router>

當應用程式啟動時,Blazor 會檢查 AppAssembly 屬性,了解哪個組件需要掃描。 其會掃描組件中,具有 RouteAttribute 的元件。 Blazor 會使用這些值編譯 RouteData 物件,而此物件會指定要求路由到元件的方式。 當您撰寫應用程式的程式碼時,您會在每個元件中,使用 @page 指示詞修正 RouteAttribute

在上述程式碼中 <Found> 標籤會指定執行階段期間,負責處理路由的 RouteView 元件。 此元件會從 URI 或查詢字串,接收 RouteData 物件和任何參數。 接著轉譯指定的元件及其版面配置。 您可以使用 <Found> 標籤指定預設版面配置。當選取的元件未使用指示詞 @layout 指定版面配置時,就會使用此預設版面配置。 之後本課程模組將會說明版面配置。

<Router> 元件中,您也可以使用 <NotFound> 標籤,指定當沒有適合的路由時,應傳回什麼內容給使用者。 上述範例會傳回一段 <p>,但您可以呈現更複雜的 HTML。 例如可以包含一個首頁連結,也可以是網站管理員的連絡頁面。

使用 @page 指示詞

在 Blazor 元件中,@page ,指示詞指定元件應直接處理要求。 您可以在 @page 指示詞中指定 RouteAttribute,方法是以字串方式傳遞。 例如,此屬性會指定由頁面處理 /Pizzas 路由的要求:

@page "/Pizzas"

若要為元件指定多個路由,請使用兩 (含) 個以上的 @page 指示詞,如此範例中所示:

@page "/Pizzas"
@page "/CustomPizzas"

取得位置資訊,然後使用 NavigationManager 巡覽

假設您撰寫了一個元件處理使用者要求的 URI,例如 http://www.contoso.com/pizzas/margherita/?extratopping=pineapple

當您撰寫元件時,可能需要存取瀏覽資訊,像是:

  • 最新完整的 URI,例如 http://www.contoso.com/pizzas/margherita?extratopping=pineapple
  • 基底 URI,例如 http://www.contoso.com/
  • 基底相對路徑,例如 pizzas/margherita
  • 查詢字串,例如 ?extratopping=pineapple

您可以使用 NavigationManager 物件取得所有這些值。 您必須將物件插入元件,才能存取其屬性。 此程式碼使用 NavigationManager 物件取得網站的基底 URI,再使用該 URI 設定首頁的連結:

@page "/pizzas"
@inject NavigationManager NavManager

<h1>Buy a Pizza</h1>

<p>I want to order a: @PizzaName</p>

<a href=@HomePageURI>Home Page</a>

@code {
    [Parameter]
    public string PizzaName { get; set; }
    
    public string HomePageURI { get; set; }
    
    protected override void OnInitialized()
    {
        HomePageURI = NavManager.BaseUri;
    }
}

若要存取查詢字串,必須剖析完整的 URI。 若要執行此剖析,請使用 Microsoft.AspNetCore.WebUtilities 組件的 QueryHelpers 類別:

@page "/pizzas"
@using Microsoft.AspNetCore.WebUtilities
@inject NavigationManager NavManager

<h1>Buy a Pizza</h1>

<p>I want to order a: @PizzaName</p>

<p>I want to add this topping: @ToppingName</p>

@code {
    [Parameter]
    public string PizzaName { get; set; }
    
    private string ToppingName { get; set; }
    
    protected override void OnInitialized()
    {
        var uri = NavManager.ToAbsoluteUri(NavManager.Uri);
        if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("extratopping", out var extraTopping))
        {
            ToppingName = System.Convert.ToString(extraTopping);
        }
    }
}

部署了上述元件之後,若使用者要求 URI http://www.contoso.com/pizzas?extratopping=Pineapple ,將會在呈現的頁面中顯示下列訊息:「我想要加入此配料:鳳梨」。

您也可以呼叫 NavigationManager.NavigateTo(),再使用 NavigationManager 物件,將您的使用者傳送給程式碼中的其他元件:

@page "/pizzas/{pizzaname}"
@inject NavigationManager NavManager

<h1>Buy a Pizza</h1>

<p>I want to order a: @PizzaName</p>

<button class="btn" @onclick="NavigateToPaymentPage">
    Buy this pizza!
</button>

@code {
    [Parameter]
    public string PizzaName { get; set; }
    
    private void NavigateToPaymentPage()
    {
        NavManager.NavigateTo("buypizza");
    }
}

注意

您傳遞給 NavigateTo() 方法的字串,是您要用以傳送使用者的絕對或相對 URI。 請確定該位址上已有設定元件。 在前述的程式碼中,將由包含 @page "/buypizza" 指示詞的元件處理此路由。

在前述的一個範例中,使用了程式碼取得 NavigationManager.BaseUri 值,並使用該值將 <a> 標籤的 href 屬性設定為首頁。 Blazor 會使用 NavLink 元件來轉譯 <a> 標籤,因為該標籤會在連結的 active 的屬性符合目前 URL 時,切換 href CSS 類別。 您可以設定 active 類別的樣式,讓使用者明確知道目前頁面的瀏覽連結。

當您使用 NavLink 時,首頁連結範例類似下列程式碼所示:

@page "/pizzas"
@inject NavigationManager NavManager

<h1>Buy a Pizza</h1>

<p>I want to order a: @PizzaName</p>

<NavLink href=@HomePageURI Match="NavLinkMatch.All">Home Page</NavLink>

@code {
    [Parameter]
    public string PizzaName { get; set; }
    
    public string HomePageURI { get; set; }
    
    protected override void OnInitialized()
    {
        HomePageURI = NavManager.BaseUri;
    }
}

NavLink 元件中的 Match 屬性用於管理連結醒目提示的時機。 有兩個選項:

  • NavLinkMatch.All:當您使用此值時,只有在連結的 href 符合目前整個 URL 時,才會將連結醒目提示為使用中的連結。
  • NavLinkMatch.Prefix:當您使用此值時,只有在連結符合的 href 符合目前 URL 的第一部分時,才會將連結醒目提示為使用中。 舉例來說,假設您有連結 <NavLink href="pizzas" Match="NavLinkMatch.Prefix">。 當目前 URL 為 http://www.contoso.com/pizzas,以及該 URL 中的任何區段與其相符 (例如 http://www.contoso.com/pizzas/formaggio) 時,就會將此連結醒目提示為使用中。 此行為有助於使用者了解他們目前正在檢視網站的哪一個區段。

檢定您的知識

1.

在 Blazor 元件中,您應使用哪個元件取得 URI 位置資訊?

2.

當 NavLink 參考目前的 URL 時,NavLink 元件會為錨點標籤新增哪個預設 CSS 類別?