使用 Blazor 路由器组件控制应用的导航

已完成

Blazor 的路由系统提供灵活的选项,可用于确保用户请求到达可处理它们并返回用户想要的信息的组件。

假设你在建设披萨派送公司的网站。 你想要设置站点,以便用同一组件处理对披萨详细信息和自定义配料详细信息的请求。 你已完成此阶段,但测试显示配料请求在接收错误消息。 需要解决此问题。

在这里,你将了解如何使用 @page 指令在 Blazor 中配置路由。

注意

本单元中的代码块是说明性示例。 你将在下一单元中编写自己的代码。

使用路由模板

用户请求你的 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 组件。 此组件接收 RouteData 对象以及来自 URI 或查询字符串的任何参数。 然后,它呈现指定的组件及其布局。 可以使用 <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,然后使用它来设置主页的链接:

@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> 标记,因为它在链接的 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 的第一部分匹配时,该链接就突出显示为活动链接。 例如,假设你拥有链接 <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 类是什么?