【Blazor】|?總結/Edison Zhou
大家好,我是Edison。許久沒有更新Blazor學習系列了,今天續更。
Blazor 的路由系統就和 ASP.NET MVC的路由系統一樣,可以為我們提供靈活的選項,可用于確保用戶請求到達可處理它們并返回用戶想要的信息的組件。
本篇,我們來了解下在Blazor中的路由系統。
使用路由模板在 Blazor 中,使用路由來確保將每個請求發送到最適合的組件,并且該組件具有顯示用戶所需內容的全部信息。
Blazor 使用名為 Router 組件的專用組件路由請求。它在 App.razor 中配置如下:
<Router AppAssembly="@typeof(App).Assembly"><Found Context="routeData"><RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /><FocusOnNavigate RouteData="@routeData" Selector="h1" /></Found><NotFound><PageTitle>Not found</PageTitle><LayoutView Layout="@typeof(MainLayout)"><p role="alert">Sorry, there's nothing at this address.</p></LayoutView></NotFound>
</Router>
應用啟動時,Blazor 會檢查 AppAssembly 屬性,以了解它應掃描哪個程序集。它會掃描該程序集,以尋找具有 RouteAttribute 的組件。Blazor 使用這些值編譯 RouteData 對象,該對象指定如何將請求路由到組件。編寫應用代碼時,可以在每個組件中使用?@page 指令來修復 RouteAttribute。
在上面的模板中,標記指定了在運行時處理路由的組件:RouteView組件。此組件接收 RouteData 對象以及來自 URI 或查詢字符串的任何參數。然后,它呈現指定的組件及其布局。可以使用??標記來指定默認布局,當所選組件未通過?@layout 指令指定布局時,將使用該布局。本模塊稍后會詳細介紹這些布局。
在??組件中,還可使用??標記指定在不存在匹配路由時返回給用戶的內容。上面的示例返回單個?
?段落和錯誤消息提示"Sorry, there's nothing at this address.",但你可以呈現更復雜的 HTML。例如,可能包括指向主頁或站點管理員聯系人頁面的鏈接。
使用@page指令
在 Blazor 組件中,@page 指令指定該組件應直接處理請求。
可以在?@page 指令中指定 RouteAttribute,方法是以字符串的形式傳遞它。例如,使用此屬性指定頁面處理對 /Todo 路由的請求:
@page "/Todo"
如果要指定到組件的多個路由,請使用兩個或更多?@page 指令:
@page "/Todo"
@page "/TodoItems"
使用NavigationManager導航
在 Blazor 組件中,如果我們需要訪問一些導航信息,如當前完整的URI、相對路徑 又或是 查詢字符串(QueryString)等,我們可以在代碼中通過 NavigationManager 對象來獲取所有的這些值。
需要注意的是,我們需要將其注入組件,才能訪問其屬性。如下代碼所示,我們通過@inject指令完成了注入。
@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}
}
如果想要訪問查詢字符串(QueryString),則必須分析完整的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(){StringValues extraTopping;var uri = NavManager.ToAbsoluteUri(NavManager.Uri);if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("extratopping", out extraTopping)){ToppingName = System.Convert.ToString(extraTopping);}}
}
最后,我們還可以通過調用 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");}
}
使用NavLink組件
在 Blazor 中,使用 NavLink 組件來呈現標記,因為它在鏈接的 href 屬性與當前 URL 匹配時將切換 active 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 的第一部分匹配時,該鏈接就突出顯示為活動鏈接。例如,假設你擁有鏈接?
。當前 URL 為?http://www.mypizza.com/pizzas?及該 URL 中的任意位置(例如?http://www.mypizza.com/pizzas/formaggio)時,此鏈接將突出顯示為活動鏈接。此行為可幫助用戶了解自己當前正在查看網站的哪一部分。
使用路由參數
在日常開發中,有時候希望將URI中的其他部分用作呈現的頁面中的值,例如:http://edtalk.com/favoritestar/jaychou。如果我們想要在Blazor中獲取到jaychou,就可以使用路由參數。
下面的示例代碼就展示了@page 指令中使用大括號來指定路由參數并為其命名。
@page "/Favorite/{favorite}"<h1>Choose a Star</h1><p>Your favorite star is: @Favorite</p>@code {[Parameter]public string Favorite { get; set; }
}
如果該路由參數并不是必須的,我們可以設置默認值,使其成為可選的路由參數。
@code {[Parameter]public string Favorite { get; set; }protected override void OnInitialized(){Favorite ??= "Fiorentina";}
}
假如用戶嘗試通過請求URI http://edtalk.com/favoritestar/jaychou/edisonchen 來指定兩個最喜愛的明星,頁面將顯示:"Your favorite start is : jaychou",并忽略后續的"edisonchen"。因此,如果我們想要顯示的是"jaychou/edisonchen",那么我們可以捕獲全部路由參數,只需要做以下一點點的修改,將星號 (*) 作為路由參數名稱前綴即可捕獲:
@page "/Favorite/{*favorites}"<h1>Choose a Star</h1><p>Your favorites star are: @Favorites</p>@code {[Parameter]public string Favorites { get; set; }
}
此外,我們可以對路由參數做類型限制,比如將其限制為一個int類型:
@page "/myorders/{orderId:int}"
除了int之外,還闊以添加的約束有 bool, datetime, decimal, double, float, guid 和 long 類型。
小結
本篇,我們了解了在Blazor中的路由系統。
下一篇,我們學習一下在Blazor中的布局系統。
參考資料
Microsoft Learn,《使用Blazor構建Web應用程序》
年終總結:Edison的2021年終總結
數字化轉型:我在傳統企業做數字化轉型
C#刷題:C#刷劍指Offer算法題系列文章目錄
.NET面試:.NET開發面試知識體系
.NET大會:2020年中國.NET開發者大會PDF資料