ASP.NET Core Blazor 레이아웃ASP.NET Core Blazor layouts

작성자: Rainer StropekLuke LathamBy Rainer Stropek and Luke Latham

메뉴, 저작권 메시지, 회사 로고 등의 일부 앱 요소는 일반적으로 앱의 전체 레이아웃에 포함되며 앱의 모든 구성 요소에서 사용됩니다.Some app elements, such as menus, copyright messages, and company logos, are usually part of app's overall layout and used by every component in the app. 이러한 요소의 코드를 앱의 모든 구성 요소에 복사하는 것은 효율적이지 않습니다.Copying the code of these elements into all of the components of an app isn't an efficient approach. 요소 중 하나에 업데이트가 필요할 때마다 모든 구성 요소를 업데이트해야 합니다.Every time one of the elements requires an update, every component must be updated. 해당 중복은 유지 관리하기 어렵고, 시간이 지남에 따라 일관성 없는 콘텐츠가 발생할 수 있습니다.Such duplication is difficult to maintain and can lead to inconsistent content over time. ‘레이아웃’을 통해 이 문제를 해결할 수 있습니다.Layouts solve this problem.

기술적으로 레이아웃은 또 다른 구성 요소입니다.Technically, a layout is just another component. 레이아웃은 Razor 템플릿 또는 C# 코드에서 정의되며 데이터 바인딩, 종속성 주입 및 기타 구성 요소 시나리오를 사용할 수 있습니다.A layout is defined in a Razor template or in C# code and can use data binding, dependency injection, and other component scenarios.

‘구성 요소’를 ‘레이아웃’으로 전환하기 위해 구성 요소는 다음을 수행합니다. To turn a component into a layout, the component:

  • 레이아웃 내부에 렌더링된 콘텐츠의 Body 속성을 정의하는 LayoutComponentBase에서 상속합니다.Inherits from LayoutComponentBase, which defines a Body property for the rendered content inside the layout.
  • Razor 구문 @Body를 사용하여 콘텐츠가 렌더링되는 위치를 레이아웃 태그에 지정합니다.Uses the Razor syntax @Body to specify the location in the layout markup where the content is rendered.

다음 코드 샘플은 레이아웃 구성 요소인 MainLayout.razor의 Razor 템플릿을 보여 줍니다.The following code sample shows the Razor template of a layout component, MainLayout.razor. 레이아웃은 LayoutComponentBase를 상속하고 탐색 모음과 바닥글 사이에 @Body를 설정합니다.The layout inherits LayoutComponentBase and sets the @Body between the navigation bar and the footer:

@inherits LayoutComponentBase

<header>
    <h1>Doctor Who&trade; Episode Database</h1>
</header>

<nav>
    <a href="masterlist">Master Episode List</a>
    <a href="search">Search</a>
    <a href="new">Add Episode</a>
</nav>

@Body

<footer>
    @TrademarkMessage
</footer>

@code {
    public string TrademarkMessage { get; set; } = 
        "Doctor Who is a registered trademark of the BBC. " +
        "https://www.doctorwho.tv/";
}

MainLayout 구성 요소MainLayout component

Blazor 프로젝트 템플릿 중 하나를 기반으로 하는 앱에서 MainLayout 구성 요소(MainLayout.razor)는 앱의 Shared 폴더에 있습니다.In an app based on one of the Blazor project templates, the MainLayout component (MainLayout.razor) is in the app's Shared folder:

@inherits LayoutComponentBase

<div class="sidebar">
    <NavMenu />
</div>

<div class="main">
    <div class="content px-4">
        @Body
    </div>
</div>

기본 레이아웃Default layout

앱의 App.razor 파일에 있는 Router 구성 요소에서 기본 앱 레이아웃을 지정합니다.Specify the default app layout in the Router component in the app's App.razor file. 기본 Blazor 템플릿에서 제공하는 다음 Router 구성 요소는 MainLayout 구성 요소에 기본 레이아웃을 설정합니다.The following Router component, which is provided by the default Blazor templates, sets the default layout to the MainLayout component:

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

NotFound 콘텐츠의 기본 레이아웃을 제공하려면 NotFound 콘텐츠에 대해 LayoutView를 지정합니다.To supply a default layout for NotFound content, specify a LayoutView for NotFound content:

<Router AppAssembly="@typeof(Startup).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <h1>Page not found</h1>
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

Router 구성 요소에 대한 자세한 내용은 ASP.NET Core Blazor 라우팅을 참조하세요.For more information on the Router component, see ASP.NET Core Blazor 라우팅.

라우터에서 레이아웃을 기본 레이아웃으로 지정하는 경우 구성 요소별 또는 폴더별로 재정의할 수 있기 때문에 유용합니다.Specifying the layout as a default layout in the router is a useful practice because it can be overridden on a per-component or per-folder basis. 가장 일반적인 방법이므로 라우터를 사용하여 앱의 기본 레이아웃을 설정하는 것이 좋습니다.Prefer using the router to set the app's default layout because it's the most general technique.

구성 요소에서 레이아웃 지정Specify a layout in a component

Razor 지시문 @layout을 사용하여 구성 요소에 레이아웃을 적용할 수 있습니다.Use the Razor directive @layout to apply a layout to a component. 컴파일러는 @layout을 구성 요소 클래스에 적용되는 LayoutAttribute로 변환합니다.The compiler converts @layout into a LayoutAttribute, which is applied to the component class.

다음 MasterList 구성 요소의 콘텐츠는 MasterLayout@Body 위치에 삽입됩니다.The content of the following MasterList component is inserted into the MasterLayout at the position of @Body:

@layout MasterLayout
@page "/masterlist"

<h1>Master Episode List</h1>

구성 요소에서 직접 레이아웃을 지정하면 라우터에서 설정된 ‘기본 레이아웃’이나 _Imports.razor에서 가져온 @layout 지시문이 재정의됩니다.Specifying the layout directly in a component overrides a default layout set in the router or an @layout directive imported from _Imports.razor.

중앙에서 레이아웃 선택Centralized layout selection

앱의 모든 폴더에 이름이 _Imports.razor인 템플릿 파일을 선택적으로 포함할 수 있습니다.Every folder of an app can optionally contain a template file named _Imports.razor. 컴파일러는 imports 파일에 지정된 지시문을 동일한 폴더와 모든 하위 폴더의 모든 Razor 템플릿에 포함합니다.The compiler includes the directives specified in the imports file in all of the Razor templates in the same folder and recursively in all of its subfolders. 따라서 _Imports.razor 파일에 @layout MyCoolLayout을 포함하면 폴더의 모든 구성 요소가 MyCoolLayout을 사용하게 됩니다.Therefore, an _Imports.razor file containing @layout MyCoolLayout ensures that all of the components in a folder use MyCoolLayout. 폴더와 하위 폴더에 있는 모든 .razor 파일에 @layout MyCoolLayout을 반복적으로 추가할 필요가 없습니다.There's no need to repeatedly add @layout MyCoolLayout to all of the .razor files within the folder and subfolders. @using 지시문은 구성 요소에도 동일한 방식으로 적용됩니다.@using directives are also applied to components in the same way.

다음 _Imports.razor 파일은 아래 항목을 가져옵니다.The following _Imports.razor file imports:

  • MyCoolLayout.MyCoolLayout.
  • 동일한 폴더와 하위 폴더에 있는 모든 Razor 구성 요소.All Razor components in the same folder and any subfolders.
  • BlazorApp1.Data 네임스페이스.The BlazorApp1.Data namespace.
@layout MyCoolLayout
@using Microsoft.AspNetCore.Components
@using BlazorApp1.Data

_Imports.razor 파일은 Razor 뷰 및 Pages용 _ViewImports.cshtml 파일과 유사하지만, 구체적으로 Razor 구성 요소 파일에 적용됩니다.The _Imports.razor file is similar to the _ViewImports.cshtml file for Razor views and pages but applied specifically to Razor component files.

_Imports.razor에서 레이아웃을 지정하면 라우터의 ‘기본 레이아웃’으로 지정된 레이아웃이 재정의됩니다.Specifying a layout in _Imports.razor overrides a layout specified as the router's default layout.

경고

루트 _Imports.razor 파일에 Razor @layout 지시어를 추가하지 마세요. 그러면 앱에서 레이아웃의 무한 루프가 발생합니다.Do not add a Razor @layout directive to the root _Imports.razor file, which results in an infinite loop of layouts in the app. 기본 앱 레이아웃을 제어하려면 Router 구성 요소에서 레이아웃을 지정합니다.To control the default app layout, specify the layout in the Router component. 자세한 내용은 기본 레이아웃 섹션을 참조하세요.For more information, see the Default layout section.

중첩된 레이아웃Nested layouts

앱은 중첩된 레이아웃으로 구성될 수 있습니다.Apps can consist of nested layouts. 구성 요소는 레이아웃을 참조할 수 있고, 레이아웃은 자기 다른 레이아웃을 참조합니다.A component can reference a layout which in turn references another layout. 예를 들어 레이아웃 중첩은 여러 수준의 메뉴 구조를 만드는 데 사용됩니다.For example, nesting layouts are used to create a multi-level menu structure.

다음 예제에서는 중첩된 레이아웃을 사용하는 방법을 보여 줍니다.The following example shows how to use nested layouts. EpisodesComponent.razor 파일은 표시할 구성 요소입니다.The EpisodesComponent.razor file is the component to display. 이 구성 요소는 MasterListLayout을 참조합니다.The component references the MasterListLayout:

@layout MasterListLayout
@page "/masterlist/episodes"

<h1>Episodes</h1>

MasterListLayout.razor 파일은 MasterListLayout을 제공합니다.The MasterListLayout.razor file provides the MasterListLayout. 레이아웃은 해당 레이아웃이 렌더링되는 다른 레이아웃인 MasterLayout을 참조합니다.The layout references another layout, MasterLayout, where it's rendered. EpisodesComponent@Body가 표시되는 위치에 렌더링됩니다.EpisodesComponent is rendered where @Body appears:

@layout MasterLayout
@inherits LayoutComponentBase

<nav>
    <!-- Menu structure of master list -->
    ...
</nav>

@Body

최종적으로, MasterLayout.razorMasterLayout에는 헤더, 주 메뉴, 바닥글 등의 최상위 레이아웃 요소가 포함됩니다.Finally, MasterLayout in MasterLayout.razor contains the top-level layout elements, such as the header, main menu, and footer. EpisodesComponent를 포함하는 MasterListLayout@Body가 표시되는 위치에 렌더링됩니다.MasterListLayout with the EpisodesComponent is rendered where @Body appears:

@inherits LayoutComponentBase

<header>...</header>
<nav>...</nav>

@Body

<footer>
    @TrademarkMessage
</footer>

@code {
    public string TrademarkMessage { get; set; } = 
        "Doctor Who is a registered trademark of the BBC. " +
        "https://www.doctorwho.tv/";
}

통합 구성 요소와 Razor Pages 레이아웃 공유Share a Razor Pages layout with integrated components

라우팅 가능한 구성 요소가 Razor Pages 앱에 통합된 경우 구성 요소와 함께 앱의 공유 레이아웃을 사용할 수 있습니다.When routable components are integrated into a Razor Pages app, the app's shared layout can be used with the components. 자세한 내용은 Razor Pages 및 MVC 앱에 ASP.NET Core Razor 구성 요소 통합를 참조하세요.For more information, see Razor Pages 및 MVC 앱에 ASP.NET Core Razor 구성 요소 통합.

추가 자료Additional resources