Blazor布局类似于母版页的ASP WebForms概念,并且与ASP MVC中的Razor布局相同。
几乎Web上的每个网站都有一个模板,该模板可以在整个网站中使用(页面顶部的品牌,底部的版权),也可以在网站的特定子部分中使用(例如,网站管理页面上的特定菜单结构)。
这是通过创建一个视图来实现的,该视图充当当前页面内容的HTML包装器,模板包含一个占位符,指示包装页面的内容应该出现在哪里。

  1. <h1>This is the start of my reusable layout</h1>
  2. <div class="Content">
  3. -- Some kind of indicator to specify the page's content will go here --
  4. </div>
  5. <footer>
  6. This is the end of the layout
  7. </footer>

然后,各个页面可以有选择地指定它想要用来包装其内容的单个布局。

  1. -- Some way of indicating which template to wrap this page's content in --
  2. <h1>This is the content of your embedded page</h1>

生成的HTML将如下所示

  1. <h1>This is the start of my reusable layout</h1>
  2. <div class="Content">
  3. <h1>This is the content of your embedded page</h1>
  4. </div>
  5. <footer>
  6. This is the end of the layout
  7. </footer>

Create a Blazor layout

您打算用作页面布局模板的任何内容都必须来自 LayoutComponentBase class。若要指示页面内容的显示位置,只需输出 Body 属性的内容即可。

  1. @inherits LayoutComponentBase
  2. <div class="main">
  3. <header>
  4. <h1>This is the header</h1>
  5. </header>
  6. <div class="content">
  7. @Body
  8. </div>
  9. <footer>
  10. This is the footer
  11. </footer>
  12. </div>

注意,这不是整个 HTML 页面。Blazor 布局只能在 Blazor 在 wwwroot\index.html 页面中定义的 HTML 部分中工作,在 Blazor 默认应用程序中,这是 元素中的所有内容。除非使用 JavaScript Interop,否则目前不可能在这个范围之外修改 HTML 元素的属性。
image.png

Using a layout

Specifying a defualt layout for the app

指定布局最通用的方法是编辑 /Pages/_Imports.razor 文件并编辑单行代码以标识不同的布局。

  1. @layout MainLayout

布局的名称是强类型的。Blazor 只会在指定名称的布局中正确地突出显示代码,如果标识符不正确,编译器也会失败。

注意: 如果您只想改变现有布局的外观,那么显然可以修改 /Shared/MainLayout.razor 文件。

Specifying a default template for an area of the app

如果你的应用程序有单独的区域(area),比如一个“ Admin”区域,你可以简单地指定一个默认布局来使用该区域内的所有页面,只需将它们分组到有自己的 _Imports.razor 文件的子文件夹中即可。

Example

创建一个新的 Blazor 客户端应用程序,然后更新导航菜单,以包含一个链接,指向我们即将创建的新页面。

  1. 打开 /Shared/NavMenu.razor 文件。
  2. 找到最后一个 <div> 元素,它应该包含一个 <navlink> 元素。
  3. 复制 <div> 元素。
  4. 将 NavLink 的 href 属性更改为"admin/users"
  5. 将链接的文本更改为 Admin users

接下来我们将创建一个非常基本的页面。

  1. 在解决方案资源管理器中展开 /Pages 节点。
  2. 创建一个名为 Admin 的文件夹。
  3. 在文件夹中创建一个名为 AdminUsers.razor 的新文件。 ```csharp @page “/admin/users”

Users</h2

  1. > 注意: 页面的 URL 不必反映文件夹结构。
  2. 现在运行该应用程序将提供一个应用程序,有一个新的菜单项命名为“Admin users”。当你点击该项目,它会显示一个非常基本的网页,只是说“Users”。接下来,我们将为所有管理页面创建一个默认布局。
  3. 1. **Admin** 文件夹中创建另一个名为 **_Imports.razor** 的新文件。
  4. 1. 输入以下代码
  5. ```csharp
  6. @layout AdminLayout

此时,名为 AdminLayout 的应用程序中没有文件,因此您应该会看到 visualstudio 中名称下方的红色线,表示找不到该文件。您可以通过在 /Shared 文件夹中创建 AdminLayout.razor 来解决这个问题。

  1. @inherits LayoutComponentBase
  2. <h1>Admin</h1>
  3. @Body

如果你现在运行这个应用程序并点击 Admin users 链接,你会看到一个糟糕的用户体验,仅仅是一个

和一个

。我们将在嵌套布局一节中解决这个问题,但是现在我们将使用它作为一个练习,学习如何从页面本身显式地指定布局。

Specifying a layout explicitly for an individual page

到目前为止,我们已经看到可以在 /Pages/_Imports.razor 文件中指定默认布局。我们还看到 Blazor 可以重写这个设置,找到一个更特定的 _Imports.razor 文件,使它更接近它正在呈现的页面。指定要使用的模板的最终(也是最明确的)级别是使用 @layout 指令在页面本身中指定它。

  1. @page "/admin/users"
  2. @layout MainLayout
  3. <h2>Users</h2>

再次运行该应用程序,点击 Admin users 链接,现在将显示使用该应用程序的标准布局的基本页面。

Nested layouts

在指定 @layout (显式地或通过 _Imports.razor 文件)时,Blazor 将用 LayoutAttribute 装饰生成的目标类。

  1. [Microsoft.AspNetCore.Components.LayoutAttribute(typeof(MainLayout))]
  2. public class AdminUsers : Microsoft.AspNetCore.Components.ComponentBase
  3. {
  4. }

注意: 生成的 .cs 文件可以在项目的 obj\Debug\netstandard2.0\Razor 文件夹中找到。

Blazor将对任何ComponentBase后代授予LayoutAttribute。不仅页面是从这个类派生出来的,LayoutComponentBase也是如此!这意味着自定义布局也可以有其自己的父布局。

Example

接下来,我们将创建一个自定义的布局。

  1. 修改 /Shared/AdminLayout.razor 文件。
  2. 通过添加@Layout MainLayout显式声明它使用MainLayout作为其父对象。 ```csharp @inherits LayoutComponentBase @layout MainLayout

Admin

@Body `` 首先,我们从LayoutComponentBase下行视图,然后告诉Blazor我们希望此布局包含在MainLayout Razor视图中,最后通过输出Body属性的内容呈现消费视图声明的任何内容。<br />为了确保**AdminUsers**页面使用**AdminLayout**,请确保**AdminUsers.razor**文件的顶部没有显式的@Layout`。这将告诉Blazor使用Pages/Admin/_Imports.razor中指定的布局。
image.png