ASP.NET Core Blazor 布局ASP.NET Core Blazor layouts
本文内容
作者:Rainer Stropek 和 Luke Latham
有些应用元素(例如菜单、版权消息和公司徽标)通常是应用整体布局的一部分,并被应用中的每个组件使用。将这些元素的代码复制到应用的所有组件中并不是高效的方法 — 每当其中一个元素需要更新,每个组件都必须更新。此类复制难以维护,并会随时间推移导致内容不一致。布局可解决此问题。
从技术上讲,布局也是一个组件。布局在 Razor 模板或 C# 代码中定义,并可使用数据绑定、依赖项注入和其他组件方案。
若要将组件转换为布局,该组件应:
- 继承自
LayoutComponentBase
,后者为布局内的呈现内容定义Body
属性。 - 使用 Razor 语法
@Body
在布局标记中指定呈现内容的位置。
以下代码示例显示布局组件 MainLayout.razor 的 Razor 模板。布局继承 LayoutComponentBase
并在导航栏和页脚之间设置 @Body
:
@inherits LayoutComponentBase
<header>
<h1>Doctor Who™ Episode Database</h1>
</header>
<nav>
<a href="masterlist">Master Episode List</a>
<a href="search">Search</a>
<a href="new">Add Episode</a>
</nav>
@Body
<footer>
@TrademarkMessage
</footer>
@code {
public string TrademarkMessage { get; set; } =
"Doctor Who is a registered trademark of the BBC. " +
"https://www.doctorwho.tv/";
}
在基于其中一个 Blazor 应用模板的应用中,MainLayout
组件 (MainLayout.razor) 位于应用的 Shared 文件夹中。
默认布局Default layout
在应用的 App.razor 文件的 Router
组件中指定默认应用布局。默认 Blazor 模板提供的以下 Router
组件将默认布局设置为 MainLayout
组件:
<Router AppAssembly="typeof(Startup).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<p>Sorry, there's nothing at this address.</p>
</NotFound>
</Router>
若要为 NotFound
内容提供默认布局,请为 NotFound
内容指定 LayoutView
:
<Router AppAssembly="typeof(Startup).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="typeof(MainLayout)">
<h1>Page not found</h1>
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
有关 Router
组件的详细信息,请参阅 ASP.NET Core Blazor 路由。
在路由器中将布局指定为默认布局是一种有用的做法,因为可以按组件或按文件夹进行替代。最好使用路由器来设置应用的默认布局,因为这是最常规的方法。
在组件中指定布局Specify a layout in a component
使用 Razor 指令 @layout
将布局应用于组件。编译器将 @layout
转换为 LayoutAttribute
,后者应用于组件类。
以下 MasterList
组件的内容插入到 MasterLayout
中 @Body
的位置:
@layout MasterLayout
@page "/masterlist"
<h1>Master Episode List</h1>
直接在组件中指定布局会替代路由器中设置的默认布局或从 _Imports.razor 导入的 @layout
指令。
集中式布局选择Centralized layout selection
应用的每个文件夹都可以选择包含名为 Imports.razor_ 的模板文件。编译器将导入文件中指定的指令包括在同一文件夹中的所有 Razor 模板内,并在其所有子文件夹中以递归方式包括。因此,包含 @layout MyCoolLayout
的 Imports.razor 文件可确保文件夹中的所有组件都使用 MyCoolLayout
。无需将 @layout MyCoolLayout
重复添加到文件夹和子文件夹内的所有 .razor_ 文件。@using
指令也以相同的方式应用于组件。
以下 _Imports.razor 文件导入:
MyCoolLayout
。- 同一文件夹以及任何子文件夹中的所有 Razor 组件。
BlazorApp1.Data
命名空间。
@layout MyCoolLayout
@using Microsoft.AspNetCore.Components
@using BlazorApp1.Data
_Imports.razor 文件类似于 Razor 视图和页面的 _ViewImports.cshtml 文件,但专门应用于 Razor 组件文件。
在 _Imports.razor 中指定布局会替代指定为路由器默认布局的布局。
嵌套布局Nested layouts
应用可以包含嵌套布局。组件可以引用一个布局,该布局反过来引用另一个布局。例如,嵌套布局用于创建多级菜单结构。
以下示例演示如何使用嵌套布局。EpisodesComponent.razor 文件是要显示的组件。该组件引用 MasterListLayout
:
@layout MasterListLayout
@page "/masterlist/episodes"
<h1>Episodes</h1>
MasterListLayout.razor 文件提供 MasterListLayout
。该布局引用另一个布局 MasterLayout
并在其中呈现。EpisodesComponent
在显示 @Body
的位置呈现:
@layout MasterLayout
@inherits LayoutComponentBase
<nav>
<!-- Menu structure of master list -->
...
</nav>
@Body
最后,MasterLayout.razor 中的 MasterLayout
包含顶级布局元素,例如页眉、主菜单和页脚。具有 EpisodesComponent
的 MasterListLayout
在 @Body
显示的位置呈现:
@inherits LayoutComponentBase
<header>...</header>
<nav>...</nav>
@Body
<footer>
@TrademarkMessage
</footer>
@code {
public string TrademarkMessage { get; set; } =
"Doctor Who is a registered trademark of the BBC. " +
"https://www.doctorwho.tv/";
}
与集成组件共享 Razor Pages 布局Share a Razor Pages layout with integrated components
当可路由组件集成到 Razor Pages 应用中时,该应用的共享布局可与这些组件配合使用。有关详细信息,请参阅 将 ASP.NET Core Razor 组件集成到 Razor Pages 和 MVC 应用。