使用布局生成可重用 Blazor 组件
Blazor 包含一些布局,让你可以轻松编写通用用户界面 (UI) 元素的代码,这些元素将显示在应用中的许多页面上。
假设你正在建设披萨派送公司的网站,并且你已创建大多数主要页面的内容作为一组 Blazor 组件。 你想要确保这些页面具有相同的品牌、导航菜单和页脚部分,但不想将代码复制并粘贴到多个文件中。
在这里,你将了解如何使用 Blazor 中的布局组件在多个页面上呈现通用 HTML。
注意
本单元中的代码块是说明性示例。 你将在下一单元中编写自己的代码。
什么是 Blazor 布局?
在大多数网站中,UI 元素的排列方式在多个页面之间共享。 例如,页面顶部可能有一个品牌横幅,主站点导航链接位于左侧,底部有法律免责声明。 在一个页面中编写这些通用 UI 元素的代码后,将它们复制并粘贴到所有其他页面的代码中会很繁琐。 更糟的是,如果以后有更改(例如要链接到站点的新增主要部分,或者有站点品牌重新设计)时,必须在所有单独的组件中重复相同的更改。 请改为使用布局组件来简化和重用通用 UI 元素。
Blazor 中的布局组件与引用它的所有组件共享其呈现的标记。 请将导航菜单、品牌和页脚等通用 UI 元素放在布局上。 然后,从多个其他组件引用该布局。 呈现页面时,常见元素来自布局,唯一元素(如预定的披萨的详细信息)来自发起引用的组件。 只需在布局中编写一次通用 UI 元素的代码即可。 因而,如果有品牌重新设计或其他更改,只需更正布局。 更改会自动应用于所有发起引用的组件。
编写 Blazor 布局
Blazor 布局是特定类型的组件,因此编写 Blazor 布局与编写其他组件以在应用中呈现 UI 类似。 例如,以相同的方式使用 @code
块和很多指令。 布局在扩展名为 .razor 的文件中定义。 文件通常存储在应用的“Shared”文件夹中,但你可以选择将其存储在使用它的组件可访问的任何位置。
布局组件有两个独特的要求:
- 必须继承
LayoutComponentBase
类。 - 必须在要呈现发起引用的组件内容的位置包含
@Body
指令。
@inherits LayoutComponentBase
<header>
<h1>Blazing Pizza</h1>
</header>
<nav>
<a href="Pizzas">Browse Pizzas</a>
<a href="Toppings">Browse Extra Toppings</a>
<a href="FavoritePizzas">Tell us your favorite</a>
<a href="Orders">Track Your Order</a>
</nav>
@Body
<footer>
@new MarkdownString(TrademarkMessage)
</footer>
@code {
public string TrademarkMessage { get; set; } = "All content is © Blazing Pizzas 2021";
}
备注
布局组件不包括 @page
指令,因为它们不直接处理请求,不应为它们创建路由。 引用组件使用 @page
指令。
如果从 Blazor 项目模板创建了 Blazor 应用,则该应用的默认布局为 Shared/MainLayout.razor 组件。
在 Blazor 组件中使用布局
若要使用另一个组件中的布局,请添加具有要应用布局名称的 @layout
指令。 组件的 HTML 将在 @Body
指令的位置呈现。
@page "/FavoritePizzas/{favorite}"
@layout BlazingPizzasMainLayout
<h1>Choose a Pizza</h1>
<p>Your favorite pizza is: @Favorite</p>
@code {
[Parameter]
public string Favorite { get; set; }
}
此图说明了如何将组件和布局组合在一起来呈现最终的 HTML:
如果要将模板应用于文件夹中的所有 Blazor 组件,可以使用 _Imports.razor 文件作为快捷方式。 Blazor 编译器找到此文件时,会自动在文件夹中的所有组件中包含其指令。 使用此方法,无需再将 @layout
指令添加到每个组件,适用于 _Imports.razor 文件所在文件夹及其所有子文件夹中的组件。
重要
请勿向项目的根文件夹中的 _Imports.razor 文件添加 @layout
指令,因为这会导致布局的无限循环。
如果要将默认布局应用于 Web 应用的所有文件夹中的所有组件,可以在 App.razor 组件中执行此操作,可以像在第 2 单元中学到的那样,在该组件中配置 Router 组件。 在 <RouteView>
标记中,使用 DefaultLayout
属性。
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(BlazingPizzasMainLayout)" />
</Found>
<NotFound>
<p>Sorry, there's nothing at this address.</p>
</NotFound>
</Router>
在各自 @layout
指令或 _Imports.razor 文件中指定了布局的组件将覆盖此默认布局设置。