レイアウトを使用して再利用できる Blazor コンポーネントを作成する

完了

Blazor には、アプリの多くのページに表示される共通のユーザー インターフェイス (UI) 要素を簡単にコーディングできるレイアウトが含まれています。

あなたは、宅配ピザ会社の Web サイト分野で働いていて、メイン ページのほとんどのコンテンツを、一連の Blazor コンポーネントとして作成したとします。 これらのページに、同じブランド化、ナビゲーション メニュー、フッター セクションが表示されるようにしたいと考えています。 しかし、そのコードをコピーして複数のファイルに貼り付ける必要がある状況は避けたいと思っています。

ここでは、Blazor でレイアウト コンポーネントを使用して、複数のページに共通の HTML をレンダリングする方法について学習します。

Note

このユニットのコード ブロックは実例です。 次のユニットで、独自のコードを記述します。

Blazor レイアウトとは

ほとんどの Web サイトでは、UI 要素の配置は複数のページにわたって共有されます。 たとえば、ブランド化されたバナーはページ上部に、サイト ナビゲーションの主なリンクは左下部に、法的な免責事項は最下部にあったりするでしょう。 1 つのページにこれらの共通 UI 要素のコードを書いた後に、それらをコピーして他のすべてのページのコードに貼り付けるのは面倒です。 さらに悪いことに、リンク先のサイトに新しい主要セクションができたり、サイトのブランド変更が行われたりなど、後で変更があった場合は、個々のコンポーネントすべてで同じ変更を繰り返す必要があります。 その代わりに、レイアウト コンポーネントを使用して、共通の UI 要素を合理化し、再利用します。

Blazor のレイアウト コンポーネントは、レンダリングされたマークアップを、それを参照するすべてのコンポーネントと共有するものです。 ナビゲーション メニュー、ブランド化、フッターなどの共通 UI 要素を、レイアウト上に配置します。 その後、他の複数のコンポーネントから、そのレイアウトを参照します。 ページがレンダリングされると、要求されたピザの詳細などの特有の要素は、参照している側のコンポーネントから取得されます。 しかし、共通の要素はレイアウトから取得されます。 共通の UI 要素は、レイアウト内に 1 回だけコーディングする必要があります。 その後、サイトのブランド変更やその他の変更がある場合は、レイアウトを修正するだけになります。 変更は、参照元のすべてのコンポーネントに自動的に適用されます。

Blazor レイアウトのコードを書く

Blazor レイアウトは特定の型のコンポーネントであるため、Blazor レイアウトを記述することは、アプリで UI をレンダリングする他のコンポーネントを記述するのと同様の作業です。 たとえば、@code ブロックのほか、多くのディレクティブを同じ方法で使用します。 レイアウトは、.razor 拡張子を持つファイルで定義します。 ファイルは多くの場合、アプリ内の Shared フォルダーに格納されますが、それを使用するコンポーネントからアクセスできる任意の場所に格納できます。

Blazor レイアウト コンポーネントに固有の 2 つの要件があります。

  • LayoutComponentBase クラスを継承する必要があります。
  • 参照しているコンポーネントのコンテンツをレンダリングする場所に、@Body ディレクティブを含める必要があります。
@inherits LayoutComponentBase

<header>
    <h1>Blazing Pizza</h1>
</header>

<nav>
    <a href="Pizzas">Browse Pizzas</a>
    <a href="Toppings">Browse Extra Toppings</a>
    <a href="FavoritePizzas">Tell us your favorite</a>
    <a href="Orders">Track Your Order</a>
</nav>

@Body

<footer>
    @new MarkdownString(TrademarkMessage)
</footer>

@code {
    public string TrademarkMessage { get; set; } = "All content is &copy; Blazing Pizzas 2021";
}

Note

レイアウト コンポーネントには @page ディレクティブを含めません。レイアウト コンポーネントでは要求は直接処理されず、それらへのルートが作成されないようにする必要があるためです。 代わりに、参照する側のコンポーネントで @page ディレクティブを使用します。

Blazor プロジェクト テンプレートから Blazor アプリを作成した場合は、Shared/MainLayout.razor コンポーネントがアプリの既定のレイアウトになります。

Blazor コンポーネントでレイアウトを使用する

その他のコンポーネントからレイアウトを使用するには、適用するレイアウトの名前を指定して @layout ディレクティブを追加します。 コンポーネントの HTML は、@Body ディレクティブの位置でレンダリングされます。

@page "/FavoritePizzas/{favorite}"
@layout BlazingPizzasMainLayout

<h1>Choose a Pizza</h1>

<p>Your favorite pizza is: @Favorite</p>

@code {
    [Parameter]
    public string Favorite { get; set; }
}

次の図は、コンポーネントとレイアウトを組み合わせて、最終的な HTML をレンダリングする方法を示しています。

コンポーネントからのマークアップを、レイアウトからのマークアップと組み合わせて、ページの最終的な HTML を作成する方法を示している図。

フォルダー内のすべての Blazor コンポーネントにテンプレートを適用する場合は、ショートカットとして _Imports.razor ファイルを使用できます。 Blazor コンパイラでこのファイルが検出されると、フォルダー内のすべてのコンポーネントに、ファイルのディレクティブが自動的に含められます。 この手法では、すべてのコンポーネントに @layout ディレクティブを追加する必要がなくなり、_Imports.razor ファイルと同じフォルダー内にあるコンポーネントと、そのすべてのサブフォルダー内にあるコンポーネントに適用されます。

重要

プロジェクトのルート フォルダーにある _Imports.razor ファイルには、@layout ディレクティブを追加しないでください。そうすると、レイアウトが無限ループになります。

Web アプリのすべてのフォルダーで、すべのコンポーネントに既定のレイアウトを適用する場合は、ユニット 2 で学習したように、Router コンポーネントを構成する場所である App.razor コンポーネントで、それを行うことができます。 <RouteView> タグで、DefaultLayout 属性を使用します。

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(BlazingPizzasMainLayout)" />
    </Found>
    <NotFound>
        <p>Sorry, there's nothing at this address.</p>
    </NotFound>
</Router>

独自の @layout ディレクティブまたは _Imports.razor ファイルで指定されたレイアウトを持つコンポーネントでは、この既定のレイアウト設定がオーバーライドされます。

自分の知識をチェックする

1.

Blazor ページに MyLayout という名前のレイアウトを指定する場合、正しい構文はどれですか?