如何在 Blazor 中嵌套布局和路由?
How to nest layouts and routing in Blazor?
我使用以下文件夹结构来组织我的 blazor wasm 项目:
Features
- Components
- Feature A
- Components
- Page1.razor
- Page2.razor
Index.razor
Shared
- MainLayout.razor
我已经创建了一个布局,我想在大多数功能中使用它。
我想出了以下想法,但我正在努力在 blazor 中实现它。 SubPageLayout.razor:
@inherits LayoutComponentBase
@layout MainLayout
<div>
<span>@FeatureTitle</span>
@Menu
<div class="container">
<span>@PageTitle</span>
<div class="content">
@Body
</div>
</div>
</div>
然后我将创建一个使用布局的功能 A/Index.razor 页面:
@page "/feature"
@layout SubPageLayout
<FeatureTitle>Feature A</FeatureTitle>
<Menu>
...
</Menu>
@Body
然后在Page1.razor:
@page "/feature/page-1"
<PageTitle>Page 1</PageTitle>
Content...
我有两个相关问题:
- 实现这个嵌套布局的 blazor-way 是什么?
- 如何将 localhost/feature 重定向到 localhost/feature/页面? /feature 本身只是一个包装器,为该功能的所有页面提供通用布局和导航。
Blazor 解决方案
首先,我创建了一个用作布局的组件。 Features/Components/SubPageLayout.razor
:
<div class="container">
<div class="sidebar">
<span>@Title</span>
@Menu
</div>
@PageContent
</div>
@code
{
[Parameter]
public string Title { get; set; } = String.Empty;
[Parameter]
public RenderFragment? Menu { get; set; }
[Parameter]
public RenderFragment? PageContent { get; set; }
}
现在我可以使用这个组件来创建布局了。例如。 Features/FeatureA/Components/FeatureALayout.razor
:
@inherits LayoutComponentBase
@layout MainLayout
<SubPageLayout Title="FeatureA">
<Menu>
<ul>...</ul>
</Menu>
<PageContent>
@Body
</PageContent>
</SubPageLayout>
在 Features/FeatureA/_Imports.cs
中将布局应用于该功能的所有页面:
@layout Components.FeatureALayout
从 /feature-a 重定向到 /feature-a/page-1 执行 /Features/FeatureA/Index.razor
:
@page "/feature-a"
@inject NavigationManager NavManager
@code {
protected override void OnInitialized()
{
NavManager.NavigateTo("/feature-a/page-1");
}
}
所有对我有帮助的资源:
- https://docs.microsoft.com/en-us/aspnet/core/blazor/components/layouts?view=aspnetcore-6.0#nested-layouts
- template a blazor RenderFragment to a layout from a page or component
- https://github.com/dotnet/aspnetcore/issues/16009#
- https://blazor-university.com/layouts/nested-layouts/
- https://chrissainty.com/blazor-bites-layouts/
- https://github.com/dotnet/aspnetcore/issues/16009#issuecomment-390932846
- https://github.com/dotnet/aspnetcore/issues/11671
使用 BlazorRouter 的解决方案(如 react-router)
在您的 MainLayout 中:
<nav>
<NavLink Href="/feature-a">Feature-A</MudNavLink>
</nav>
<main>
<Switch>
<Route Template="feature-a/*">
<BlazorUI.Features.FeatureA.Index />
</Route>
<Route>
<p>404</p>
</Route>
</Switch>
</main>
在Features/FeatureA/Index.razor
中:
@page "/feature-a"
@inherits LayoutComponentBase
@layout MainLayout
@inject NavigationManager NavManager
@code {
protected override void OnInitialized()
{
NavManager.NavigateTo("/feature-a/page-1");
}
}
<div class="sub-layout">
<ul>...</ul>
<div class="content">
<Switch>
<Route Template="feature-a/page-1">
<Page1/>
</Route>
<Route>
<p>No content found in nested layout</p>
</Route>
</Switch>
</div>
</div>
索引页包含嵌套布局。 Switch 将根据当前 url.
加载页面
我使用以下文件夹结构来组织我的 blazor wasm 项目:
Features
- Components
- Feature A
- Components
- Page1.razor
- Page2.razor
Index.razor
Shared
- MainLayout.razor
我已经创建了一个布局,我想在大多数功能中使用它。
我想出了以下想法,但我正在努力在 blazor 中实现它。 SubPageLayout.razor:
@inherits LayoutComponentBase
@layout MainLayout
<div>
<span>@FeatureTitle</span>
@Menu
<div class="container">
<span>@PageTitle</span>
<div class="content">
@Body
</div>
</div>
</div>
然后我将创建一个使用布局的功能 A/Index.razor 页面:
@page "/feature"
@layout SubPageLayout
<FeatureTitle>Feature A</FeatureTitle>
<Menu>
...
</Menu>
@Body
然后在Page1.razor:
@page "/feature/page-1"
<PageTitle>Page 1</PageTitle>
Content...
我有两个相关问题:
- 实现这个嵌套布局的 blazor-way 是什么?
- 如何将 localhost/feature 重定向到 localhost/feature/页面? /feature 本身只是一个包装器,为该功能的所有页面提供通用布局和导航。
Blazor 解决方案
首先,我创建了一个用作布局的组件。 Features/Components/SubPageLayout.razor
:
<div class="container">
<div class="sidebar">
<span>@Title</span>
@Menu
</div>
@PageContent
</div>
@code
{
[Parameter]
public string Title { get; set; } = String.Empty;
[Parameter]
public RenderFragment? Menu { get; set; }
[Parameter]
public RenderFragment? PageContent { get; set; }
}
现在我可以使用这个组件来创建布局了。例如。 Features/FeatureA/Components/FeatureALayout.razor
:
@inherits LayoutComponentBase
@layout MainLayout
<SubPageLayout Title="FeatureA">
<Menu>
<ul>...</ul>
</Menu>
<PageContent>
@Body
</PageContent>
</SubPageLayout>
在 Features/FeatureA/_Imports.cs
中将布局应用于该功能的所有页面:
@layout Components.FeatureALayout
从 /feature-a 重定向到 /feature-a/page-1 执行 /Features/FeatureA/Index.razor
:
@page "/feature-a"
@inject NavigationManager NavManager
@code {
protected override void OnInitialized()
{
NavManager.NavigateTo("/feature-a/page-1");
}
}
所有对我有帮助的资源:
- https://docs.microsoft.com/en-us/aspnet/core/blazor/components/layouts?view=aspnetcore-6.0#nested-layouts
- template a blazor RenderFragment to a layout from a page or component
- https://github.com/dotnet/aspnetcore/issues/16009#
- https://blazor-university.com/layouts/nested-layouts/
- https://chrissainty.com/blazor-bites-layouts/
- https://github.com/dotnet/aspnetcore/issues/16009#issuecomment-390932846
- https://github.com/dotnet/aspnetcore/issues/11671
使用 BlazorRouter 的解决方案(如 react-router)
在您的 MainLayout 中:
<nav>
<NavLink Href="/feature-a">Feature-A</MudNavLink>
</nav>
<main>
<Switch>
<Route Template="feature-a/*">
<BlazorUI.Features.FeatureA.Index />
</Route>
<Route>
<p>404</p>
</Route>
</Switch>
</main>
在Features/FeatureA/Index.razor
中:
@page "/feature-a"
@inherits LayoutComponentBase
@layout MainLayout
@inject NavigationManager NavManager
@code {
protected override void OnInitialized()
{
NavManager.NavigateTo("/feature-a/page-1");
}
}
<div class="sub-layout">
<ul>...</ul>
<div class="content">
<Switch>
<Route Template="feature-a/page-1">
<Page1/>
</Route>
<Route>
<p>No content found in nested layout</p>
</Route>
</Switch>
</div>
</div>
索引页包含嵌套布局。 Switch 将根据当前 url.
加载页面