2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Blazor ComponentのLayout機能をフル活用しよう!

Posted at

Layoutという仕組みを使って、共通ヘッダーを定義するやり方を説明します。

公式ドキュメントに沿いつつご紹介します。

環境

VS2022のBlazor Appテンプレートからプロジェクトを作成します。

Render Modeはどれを選択しても大丈夫です。

Layout Componentの作り方

@inherits LayoutComponentBaseを継承してください。

@BodyにComponentが描画されます。

シンプル化のため、本記事では記載していないですが、Layout Componentも他のComponentと同様に@codeを持つことができますので、イベント処理なども当然行うことができます。

Custom Layout
@inherits LayoutComponentBase

<h1>Custom Layout</h1>

@Body

Application全体に反映させたい場合

Routes.razorRouteViewに設定します。

Routes.razor
<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Client._Imports).Assembly }">
    <Found Context="routeData">
        @* DefaultLayoutに適用 *@
        <RouteView RouteData="routeData" DefaultLayout="typeof(Layout.CustomLayout)" />
        <FocusOnNavigate RouteData="routeData" Selector="h1" />
    </Found>
</Router>

フォルダごとに反映させたい場合

_Imports.razorファイルの特性を活かします。

このファイルに記載されたDirectiveは、_Imports.razorファイルが存在するフォルダと、そのフォルダ以下全てのRazor Componentに適用されます。

Directiveの一つとして、@layoutをすることで、指定フォルダとその配下のすべての@page を持つComponentに、共通Layoutを適用させることができます。

例えば、管理者用 Layoutと一般ユーザー用 Layoutを分けたい場合は、以下のような実装で実現可能です。

  • Layout
AdminLayout.razor
@inherits LayoutComponentBase

<h1>Admin Layout</h1>

@Body
MemberLayout.razor
@inherits LayoutComponentBase

<h1>Member Layout</h1>

@Body
  • _Imports.razor
Admin/_Imports.razor
@layout BlazorAppTips.Components.Layout.AdminLayout
Member/_Imports.razor
@layout BlazorAppTips.Components.Layout.MemberLayout
  • Component
Admin/AdminComponent
@page "/admin"

<h3>Admin Component</h3>
Member/MemberComponent
@page "/member"

<h3>Member Component</h3>
  • Tree
shell
├─Layout
│      AdminLayout.razor
│      MemberLayout.razor
└─Pages
    ├─Admin
    │      AdminComponent.razor
    │      _Imports.razor
    │
    └─Member
            MemberComponent.razor
            _Imports.razor

個別のComponentにLayoutを適用する場合

@layout Directiveを対象のComponentに記載すればOKです。

そのComponentのみにLayoutが適用されます。

特定のContentのみに適用する場合

<LayoutView> Componentを利用し、以下のように実装可能です。

例えば、Default Layoutを適用させつつ、一部のContentにのみ特定のLayoutを適用したいときに利用できます。

Compeont.razor
@page "/"

<div>Home</div>

<LayoutView Layout="typeof(ErrorLayout)">
    <h1>Nested content</h1>
    <h2>Hello</h2>
</LayoutView>

Nested Layouts

Lyout Componentに更に@layout Directiveを追加することで、Layoutを積み重ねることが可能です。

上述した、フォルダごと、ComponentごとのLayout適用はDefault Layoutを上書きします。

例えば、を維持しつつ、フォルダごとにLayoutを適用させたいという場合は、以下のように記載することで実現できます。実務でも発生するケースですね。

フォルダごとにLayout Componentを適用させた場合、<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.CustomLayout)" />で指定されているDefaultLayoutが上書きされるため、明示的にフォルダごとに適用されるLayout Componentに@layout Directiveを設定します。

  • Layout
NestedLayout.razor
@inherits LayoutComponentBase
@layout CustomLayout

<h2>NestedLayout</h2>

@Body
  • _Imports.razor
Nested/_Imports.razor
@layout BlazorAppTips.Components.Layout.NestedLayout
  • Component
Nested/Component.razor
@page "/nested"

<h3>Component</h3>
  • Tree
shell
├─Layout
│      CustomLayout.razor
│      NestedLayout.razor
└─Pages
    ├─Nested
    │      Component.razor
    │      _Imports.razor

Layout Componentが見つからない?

名前空間

いくつかの方法で対象Layout(razor component)の名前空間を適用させることができます。

BlazorAppTipsがプロジェクト名の場合です。

  • Root配下の_Imports.razorに@usingを追加
_Imports.razor
@using BlazorAppTips.Components.Layout
  • @using@layoutで名前空間とComponentを同時に指定
Component.razor
@using BlazorAppTips.Components.Layout
@layout CustomLayout
  • @layoutに名前空間とComponentをまとめて指定
Component
@layout BlazorAppTips.Components.Layout.CustomLayout

最後に

Layout Componentを利用することで、Componentの再利用性が高まります。

これにRender Modeが絡んでくると厄介で、Layout Component、Routes.razor Componentを.Clientプロジェクト側に移動する必要などが出てきます。また別の機会にそれらのユースケースは説明できればと思います。

リポジトリ

BlazorAppTips

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?