当前位置: 代码迷 >> 综合 >> Blazor University (2)布局 — 创建 Blazor 布局
  详细解决方案

Blazor University (2)布局 — 创建 Blazor 布局

热度:3   发布时间:2024-01-12 05:55:20.0

原文链接:https://blazor-university.com/layouts/

布局

Blazor 布局类似于 ASP Webforms 母版页的概念,与 ASP MVC 中的 Razor 布局相同。

几乎网络上的每个网站都有一个模板用于整个网站(页面顶部的品牌,底部的版权)或网站的特定子部分(例如站点管理页面上的特定菜单结构)。

这是通过创建一个视图来实现的,该视图充当当前页面内容的 HTML 包装器,模板包含一个占位符,指示包装页面的内容应该出现在哪里。

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

然后,各个页面可以选择指定一个布局,希望将其内容包含在其中。

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

生成的 HTML 看起来像这样

<h1>This is the start of my reusable layout</h1>
<div class="Content"><h1>This is the content of your embedded page</h1>
</div>
<footer>This is the end of the layout
</footer>

创建 Blazor 布局

源代码[1]

您打算用作页面布局模板的任何内容都必须来自 LayoutComponentBase 类。要指示您希望页面内容出现在哪里,您只需输出 Body 属性的内容。

@inherits LayoutComponentBase
<div class="main"><header><h1>This is the header</h1></header><div class="content">@Body</div><footer>This is the footer</footer>
</div>

请注意,这不是整个 HTML 页面。Blazor 布局仅适用于 Blazor 在 wwwroot\index.html 页面中定义的 HTML 部分,在默认的 Blazor 应用程序中,这是 <app> 元素中的所有内容。目前无法在此范围之外更改 HTML 元素的属性,除非使用 JavaScript 互操作。

705a39b2d216f600e1b8f908e3182950.png

使用布局

为应用程序指定默认布局

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

@layout MainLayout

布局的名称是强类型的。如果存在指定名称的布局,Blazor 会高亮正确语法的代码,如果标识符不正确,编译会失败。

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

为应用程序的某个区域指定默认模板

源代码[2]

如果您的应用程序有单独的区域,例如“Admin”区域,则可以指定用于该区域内所有页面的默认布局,只需将它们分组到具有自己的 _Imports.razor 文件的子文件夹中。

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

  • 打开 /Shared/NavMenu.razor 文件。

  • 找到最后一个 <li> 元素,它应该包含一个 <NavLink> 元素。

  • 复制 <li> 元素。

  • 将 NavLink 的 href 属性更改为 admin/users

  • 将链接的文本更改为管理员用户

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

  1. 在解决方案资源管理器中展开 /Pages 节点。

  2. 创建一个名为 Admin 的文件夹。

  3. 在文件夹中创建一个名为 AdminUsers.razor 的新文件。

@page "/admin/users"
<h2>Users</h2

注意: 页面的 URL 不必反映文件夹结构。

现在运行应用程序,该应用程序将具有一个名为“管理员用户”的新菜单项。当您单击该菜单项时,它将显示一个非常基本的页面,其中仅显示“Users”。接下来,我们将为所有管理页面创建一个默认布局。

  1. Admin 文件夹中创建另一个名为 _Imports.razor 的新文件。

  2. 输入以下代码。

@layout AdminLayout

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

@inherits LayoutComponentBase
<h1>Admin</h1>
@Body

如果您现在运行该应用程序并单击管理员用户链接,您将看到仅由 <h1><h2> 组成的简陋页面。我们将在嵌套布局部分解决这个问题,但现在我们将使用它作为练习,了解如何从页面本身显式指定布局。

为单个页面显式指定布局

源代码[3]

到目前为止,我们已经看到可以在 /Pages/_Imports.razor 文件中指定默认布局。我们还看到,可以通过 Blazor 找到更接近其正在呈现的页面的更具体的 _Imports.razor 文件来覆盖此设置。指定要使用的模板的最后(也是最明确的)级别是使用 @layout 指令在页面本身中指定它。

@page "/admin/users"
@layout MainLayout
<h2>Users</h2>

再次运行应用程序并单击管理员用户链接现在将使用应用程序的标准布局显示基本页面。

嵌套布局

源代码[4]

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

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

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

Blazor 将为任何 ComponentBase 的子类使用 LayoutAttribute。不仅页面来自这个类,而且 LayoutComponentBase 也是如此!这意味着自定义布局也可以有自己的父布局。

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

  1. 编辑 /Shared/AdminLayout.razor 文件。

  2. 通过添加 @layout MainLayout 明确声明它使用 MainLayout 作为其父级。

@inherits LayoutComponentBase
@layout MainLayout
<h1>Admin</h1>
@Body

首先,我们从 LayoutComponentBase 继承视图,然后告诉 Blazor 我们希望此布局包含在 MainLayout Razor 视图中,最后我们通过输出 Body 属性的内容来呈现使用者视图声明的任何内容。

为了确保 AdminUsers 页面使用 AdminLayout,请确保 AdminUsers.razor 文件顶部没有显式的 layout。这将告诉 Blazor 使用 Pages/Admin/_Imports.razor 中指定的布局。

@page "/admin/users"<h2>Users</h2>

b48b5bf613e6b1fe0d9fc9f3dcf418ca.png

参考资料

[1]

源代码: https://github.com/mrpmorris/blazor-university/tree/master/src/Layouts/CreatingALayout

[2]

源代码: https://github.com/mrpmorris/blazor-university/tree/master/src/Layouts/UsingALayout

[3]

源代码: https://github.com/mrpmorris/blazor-university/tree/master/src/Layouts/SpecifyingALayoutExplicitly

[4]

源代码: https://github.com/mrpmorris/blazor-university/tree/master/src/Layouts/NestedLayouts

  相关解决方案