レイアウトを使用して再利用できる 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 © 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 をレンダリングする方法を示しています。
フォルダー内のすべての 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 ファイルで指定されたレイアウトを持つコンポーネントでは、この既定のレイアウト設定がオーバーライドされます。