Compartilhar via


Layouts Blazor do ASP.NET Core

Observação

Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 9 deste artigo.

Aviso

Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, consulte a Política de Suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.

Importante

Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.

Para a versão atual, consulte a versão .NET 9 deste artigo.

Este artigo explica como criar componentes de layout reutilizáveis para aplicativos Blazor.

Utilidade dos layouts Blazor

Alguns elementos do aplicativo, como menus, mensagens de direitos autorais e logotipos da empresa, geralmente fazem parte da apresentação geral do aplicativo. A colocação de uma cópia da marcação desses elementos em todos os componentes de um aplicativo não é eficiente. Sempre que um desses elementos é atualizado, todos os componentes que usam o elemento devem ser atualizados. Essa abordagem pode custar caro para ser mantida e pode gerar um conteúdo inconsistente se uma atualização for perdida. Os layouts resolvem esses problemas.

Um layout de Blazor é um componente de Razor que compartilha a marcação com componentes que fazem referência a ele. Os layouts podem usar associação de dados, injeção de dependência e outros recursos de componentes.

Criar um componente de layout

Para criar um componente de layout:

  • Crie um componente Razor definido por um modelo Razor ou código C#. Os componentes de layout baseados em um modelo Razor usam a extensão de arquivo .razor, assim como os componentes Razor comuns. Como os componentes de layout são compartilhados entre os componentes de um aplicativo, eles geralmente são colocados na pasta Shared ou Layout do aplicativo. No entanto, os layouts podem ser colocados em qualquer local acessível aos componentes que o usam. Por exemplo, um layout pode ser colocado na mesma pasta que os componentes que o utilizam.
  • Herda o componente de LayoutComponentBase. O LayoutComponentBase define uma propriedade Body (tipo RenderFragment) para o conteúdo renderizado dentro do layout.
  • Use a sintaxe Razor@Body para especificar o local na marcação de layout em que o conteúdo é renderizado.

Observação

Para obter mais informações sobre RenderFragment, confira Componentes Razordo ASP.NET Core.

O componente DoctorWhoLayout a seguir mostra o modelo Razor de um componente de layout. O layout herda LayoutComponentBase e define o @Body entre a barra de navegação (<nav>...</nav>) e o rodapé (<footer>...</footer>).

DoctorWhoLayout.razor:

@inherits LayoutComponentBase

<PageTitle>Doctor Who® Database</PageTitle>

<header>
    <h1>Doctor Who® Database</h1>
</header>

<nav>
    <a href="main-list">Main 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/ https://www.bbc.com";
}
@inherits LayoutComponentBase

<PageTitle>Doctor Who® Database</PageTitle>

<header>
    <h1>Doctor Who® Database</h1>
</header>

<nav>
    <a href="main-list">Main 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/ https://www.bbc.com";
}
@inherits LayoutComponentBase

<header>
    <h1>Doctor Who™ Episode Database</h1>
</header>

<nav>
    <a href="main-list">Main 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/";
}
@inherits LayoutComponentBase

<header>
    <h1>Doctor Who™ Episode Database</h1>
</header>

<nav>
    <a href="main-list">Main 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/";
}
@inherits LayoutComponentBase

<header>
    <h1>Doctor Who™ Episode Database</h1>
</header>

<nav>
    <a href="main-list">Main 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/";
}
@inherits LayoutComponentBase

<header>
    <h1>Doctor Who™ Episode Database</h1>
</header>

<nav>
    <a href="main-list">Main 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/";
}

Componente MainLayout

Em um aplicativo criado com base em um modelo de projeto Blazor, o componente MainLayout é o layout padrão do aplicativo. O layout do Blazor adota a Flexbox layout model (especificação W3C).

O recurso de isolamento CSS do Blazor aplica estilos CSS isolados ao componente MainLayout. Por convenção, os estilos são fornecidos pela folha de estilos que acompanha o mesmo nome, MainLayout.razor.css. A implementação da estrutura ASP.NET Core da folha de estilos está disponível para inspeção na fonte de referência do ASP.NET Core (repositório GitHub dotnet/aspnetcore):

Observação

Os links de documentação para a fonte de referência do .NET geralmente carregam o branch padrão do repositório, que representa o desenvolvimento atual da próxima versão do .NET. Para selecionar uma marca para uma versão específica, use a lista suspensa para Alternar branches ou marcas. Para saber mais, confira Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).

O recurso de isolamento CSS do Blazor aplica estilos CSS isolados ao componente MainLayout. Por convenção, os estilos são fornecidos pela folha de estilos que acompanha o mesmo nome, MainLayout.razor.css.

Componentes de layout renderizados estaticamente

Quando uma Blazor Web App adota a renderização por página/componente (o componente Routes não especifica um modo de renderização dinâmico), os componentes de layout são renderizados de forma estática no servidor. Não há suporte para a aplicação de um modo de renderização interativo diretamente a um layout porque Blazor não dá suporte à serialização de um RenderFragment (@Body nesse caso) como um parâmetro de componente raiz. Por exemplo, colocar @rendermode InteractiveServer na parte superior do MainLayout componente resulta na seguinte exceção de runtime:

System.InvalidOperationException: não é possível passar o parâmetro 'Body' para o componente 'MainLayout' com o rendermode 'InteractiveServerRenderMode'. Isso ocorre porque o parâmetro é do tipo delegado 'Microsoft.AspNetCore.Components.RenderFragment', que é um código arbitrário e não pode ser serializado.

Isso se aplica a qualquer componente de layout que herda de LayoutComponentBase em um aplicativo que adota renderização por página/componente.

Esse cenário pode ser resolvido em uma versão futura de Blazor. Para obter mais informações, consulte [Blazor] Suporte à serialização de fragmentos de renderização do SSR (dotnet/aspnetcore nº 52768). Enquanto isso, você pode adotar a abordagem a seguir em uma Blazor Web App que adote a renderização por página/componente.

Crie um componente wrapper capaz de interatividade. No exemplo a seguir, um componente de encapsulamento contém uma seção Blazor que pode receber conteúdo de um componente filho.

No arquivo _Imports.razor, adicione uma diretiva @using para seções Microsoft.AspNetCore.Components.Sections.

@using Microsoft.AspNetCore.Components.Sections

Crie o seguinte componente de wrapper interativo na Pages pasta.

Pages/InteractiveWrapper.razor:

@rendermode InteractiveServer

<div>
    <SectionOutlet SectionName="top-bar" />
</div>

@ChildContent

@code {
    [Parameter]
    public RenderFragment? ChildContent { get; set; }
}

O Counter componente pode usar o componente wrapper e definir o conteúdo da seção interativa. No exemplo a seguir, um botão de contador é colocado na seção.

Pages/Counter.razor:

@page "/counter"
@rendermode InteractiveServer

<InteractiveWrapper>

    <SectionContent SectionName="top-bar">
        <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    </SectionContent>

    <PageTitle>Counter</PageTitle>

    <h1>Counter</h1>

    <p role="status">Current count: @currentCount</p>

    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

</InteractiveWrapper>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

Outros componentes ao redor do aplicativo também podem encapsular o conteúdo no componente e definir o InteractiveWrapper conteúdo da seção interativa.

Aplicar um layout

Disponibilizar o namespace de layout

Locais de arquivo de layout e namespaces alterados ao longo do tempo para a estrutura Blazor. Dependendo da versão de Blazor e do tipo do aplicativo Blazor que você está criando, talvez seja necessário indicar o namespace do layout ao usá-lo. Ao referenciar uma implementação de layout e o layout não for encontrado sem indicar o namespace do layout, siga qualquer uma das seguintes abordagens:

  • Adicione uma diretiva @using ao arquivo _Imports.razor para a localização dos layouts. No exemplo a seguir, uma pasta de layouts com o nome Layout está dentro de uma pasta Components e o namespace do aplicativo é BlazorSample:

    @using BlazorSample.Components.Layout
    
  • Adicione uma diretiva @using no topo da definição do componente onde o layout é usado:

    @using BlazorSample.Components.Layout
    @layout DoctorWhoLayout
    
  • Qualifique totalmente o namespace do layout em que ele é usado:

    @layout BlazorSample.Components.Layout.DoctorWhoLayout
    

Aplicar um layout a um componente

Use a diretiva @layoutRazor para aplicar um layout a um componente Razor roteável que tenha uma diretiva @page. O compilador converte @layout em um LayoutAttribute e aplica o atributo à classe de componente.

O conteúdo do componente Episodes a seguir é inserido no DoctorWhoLayout na posição de @Body.

Episodes.razor:

@page "/episodes"
@layout DoctorWhoLayout

<h2>Doctor Who® Episodes</h2>

<ul>
    <li>
        <a href="https://www.bbc.co.uk/programmes/p00vfknq">
            <em>The Ribos Operation</em>
        </a>
    </li>
    <li>
        <a href="https://www.bbc.co.uk/programmes/p00vfdsb">
            <em>The Sunmakers</em>
        </a>
    </li>
    <li>
        <a href="https://www.bbc.co.uk/programmes/p00vhc26">
            <em>Nightmare of Eden</em>
        </a>
    </li>
</ul>
@page "/episodes"
@layout DoctorWhoLayout

<h2>Doctor Who® Episodes</h2>

<ul>
    <li>
        <a href="https://www.bbc.co.uk/programmes/p00vfknq">
            <em>The Ribos Operation</em>
        </a>
    </li>
    <li>
        <a href="https://www.bbc.co.uk/programmes/p00vfdsb">
            <em>The Sunmakers</em>
        </a>
    </li>
    <li>
        <a href="https://www.bbc.co.uk/programmes/p00vhc26">
            <em>Nightmare of Eden</em>
        </a>
    </li>
</ul>
@page "/episodes"
@layout DoctorWhoLayout

<h2>Episodes</h2>

<ul>
    <li>
        <a href="https://www.bbc.co.uk/programmes/p00vfknq">
            <em>The Ribos Operation</em>
        </a>
    </li>
    <li>
        <a href="https://www.bbc.co.uk/programmes/p00vfdsb">
            <em>The Sun Makers</em>
        </a>
    </li>
    <li>
        <a href="https://www.bbc.co.uk/programmes/p00vhc26">
            <em>Nightmare of Eden</em>
        </a>
    </li>
</ul>
@page "/episodes"
@layout DoctorWhoLayout

<h2>Episodes</h2>

<ul>
    <li>
        <a href="https://www.bbc.co.uk/programmes/p00vfknq">
            <em>The Ribos Operation</em>
        </a>
    </li>
    <li>
        <a href="https://www.bbc.co.uk/programmes/p00vfdsb">
            <em>The Sun Makers</em>
        </a>
    </li>
    <li>
        <a href="https://www.bbc.co.uk/programmes/p00vhc26">
            <em>Nightmare of Eden</em>
        </a>
    </li>
</ul>
@page "/episodes"
@layout DoctorWhoLayout

<h2>Episodes</h2>

<ul>
    <li>
        <a href="https://www.bbc.co.uk/programmes/p00vfknq">
            <em>The Ribos Operation</em>
        </a>
    </li>
    <li>
        <a href="https://www.bbc.co.uk/programmes/p00vfdsb">
            <em>The Sun Makers</em>
        </a>
    </li>
    <li>
        <a href="https://www.bbc.co.uk/programmes/p00vhc26">
            <em>Nightmare of Eden</em>
        </a>
    </li>
</ul>

A marcação HTML renderizada a seguir é produzida pelo componente anterior DoctorWhoLayout e Episodes. A marcação desnecessária não aparece para se concentrar no conteúdo fornecido pelos dois componentes envolvidos:

  • O título H1 do "banco de dados" (<h1>...</h1>) no cabeçalho (<header>...</header>), a barra de navegação (<nav>...</nav>) e as informações de marca registrada no rodapé (<footer>...</footer>) são provenientes do componente DoctorWhoLayout.
  • O título H2 "episódios" (<h2>...</h2>) e a lista de episódios (<ul>...</ul>) são derivados do componente Episodes.
<header>
    <h1 ...>...</h1>
</header>

<nav>
    ...
</nav>

<h2>...</h2>

<ul>
    <li>...</li>
    <li>...</li>
    <li>...</li>
</ul>

<footer>
    ...
</footer>

A especificação do layout diretamente em um componente substitui um layout padrão:

Aplicar um layout a uma pasta de componentes

Cada pasta de um aplicativo pode, opcionalmente, conter um arquivo de modelo nomeado _Imports.razor. O compilador inclui as diretivas especificadas no arquivo de importações em todos os modelos Razor na mesma pasta e recursivamente em todas as suas subpastas. Portanto, um arquivo _Imports.razor que contém @layout DoctorWhoLayout garante que todos os componentes em uma pasta usem o componente DoctorWhoLayout. Não é necessário adicionar @layout DoctorWhoLayout repetidamente a todos os componentes Razor (.razor) dentro da pasta e das subpastas.

_Imports.razor:

@layout DoctorWhoLayout
...

O arquivo _Imports.razor é semelhante ao arquivo _ViewImports.cshtml para exibições Razor e páginas, mas aplicado especificamente aos arquivos de componente Razor.

A especificação de um layout em _Imports.razor substitui um layout especificado como layout de aplicativo padrão do roteador, que é descrito na seção a seguir.

Aviso

Não adicione uma diretiva Razor@layout ao arquivo _Imports.razor raiz, o que resulta em um loop infinito de layouts. Para controlar o layout do aplicativo padrão, especifique o layout no componente Router. Para obter mais informações, consulte a seção Aplicar um layout padrão a um aplicativo a seguir.

A mesma condição resulta ao usar um arquivo _Imports.razor para aplicar um layout a uma pasta de componentes com a diretiva @layout e o componente de layout em si está na mesma pasta ou hierarquia de pastas do arquivo _Imports.razor. Um loop infinito de aplicação do layout ocorre porque a diretiva @layout também é aplicada ao componente de layout. Para evitar problemas de recursão, recomendamos armazenar componentes de layout em sua própria pasta (por exemplo, Layouts), longe de onde _Imports.razor arquivos os estão aplicando.

Observação

A diretiva @layoutRazor aplica apenas um layout a componentes roteáveis Razor com uma diretiva @page.

Aplicar um layout padrão a um aplicativo

Especifique o layout do aplicativo padrão no componente Router do componente RouteView. Use o parâmetro DefaultLayout para definir o tipo de layout:

<RouteView RouteData="routeData" DefaultLayout="typeof({LAYOUT})" />

No exemplo anterior, o marcador de posição {LAYOUT} é o layout (por exemplo, DoctorWhoLayout se o nome do arquivo de layout for DoctorWhoLayout.razor). Talvez seja necessário identificar o namespace do layout dependendo da versão do .NET e do tipo de Blazor aplicativo. Para obter mais informações, consulte a seção Disponibilizar o namespace de layout.

A especificação do layout como um layout padrão no Router do RouteView do componente é uma prática útil porque você pode substituir o layout por componente ou por pasta, conforme descrito nas seções anteriores deste artigo. É recomendável usar o componente Router para definir o layout padrão do aplicativo, pois ele é a abordagem mais geral e flexível para usar layouts.

Aplicar um layout ao conteúdo arbitrário (componente LayoutView)

Para definir um layout para conteúdo de modelo arbitrário Razor, especifique o layout com um componente LayoutView. Você pode usar um LayoutView em qualquer componente Razor. O exemplo a seguir define um componente de layout nomeado ErrorLayout para o modelo MainLayout do componente NotFound (<NotFound>...</NotFound>).

<Router ...>
    <Found ...>
        ...
    </Found>
    <NotFound>
        <LayoutView Layout="typeof(ErrorLayout)">
            <h1>Page not found</h1>
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

Talvez seja necessário identificar o namespace do layout dependendo da versão do .NET e do tipo de Blazor aplicativo. Para obter mais informações, consulte a seção Disponibilizar o namespace de layout.

Importante

Blazor Web Apps não usam o parâmetro NotFound (marcação <NotFound>...</NotFound>), mas o parâmetro é compatível para compatibilidade com versões anteriores para evitar uma alteração significativa na estrutura. O pipeline de middleware ASP.NET Core do lado do servidor processa solicitações no servidor. Use técnicas do lado do servidor para lidar com solicitações incorretas. Para obter mais informações, consulte ASP.NET Core Blazor modos de renderização.

Observação

Com a versão do .NET 5.0.1 e para quaisquer versões adicionais de 5.x, o Router componente inclui o PreferExactMatches parâmetro definido como @true. Para obter mais informações, consulte Migrar do ASP.NET Core 3.1 para o .NET 5.

Layouts aninhados

Um componente pode fazer referência a um layout que, por sua vez, faz referência a outro layout. Por exemplo, layouts aninhados são usados para criar estruturas de menu de vários níveis.

O exemplo a seguir mostra como usar os layouts aninhados. O componente Episodes mostrado na seção Aplicar um layout a um componente é o componente a ser exibido. O componente faz referência ao componente DoctorWhoLayout.

O componente DoctorWhoLayout a seguir é uma versão modificada do exemplo mostrado anteriormente neste artigo. Os elementos de cabeçalho e rodapé são removidos e o layout faz referência a outro layout, ProductionsLayout. O componente Episodes é renderizado onde @Body aparece no DoctorWhoLayout.

DoctorWhoLayout.razor:

@inherits LayoutComponentBase
@layout ProductionsLayout

<PageTitle>Doctor Who® Database</PageTitle>

<h1>Doctor Who® Database</h1>

<nav>
    <a href="main-episode-list">Main Episode List</a>
    <a href="episode-search">Search</a>
    <a href="new-episode">Add Episode</a>
</nav>

@Body

<div>
    @TrademarkMessage
</div>

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

<PageTitle>Doctor Who® Database</PageTitle>

<h1>Doctor Who® Database</h1>

<nav>
    <a href="main-episode-list">Main Episode List</a>
    <a href="episode-search">Search</a>
    <a href="new-episode">Add Episode</a>
</nav>

@Body

<div>
    @TrademarkMessage
</div>

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

<h1>Doctor Who™ Episode Database</h1>

<nav>
    <a href="main-episode-list">Main Episode List</a>
    <a href="episode-search">Search</a>
    <a href="new-episode">Add Episode</a>
</nav>

@Body

<div>
    @TrademarkMessage
</div>

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

<h1>Doctor Who™ Episode Database</h1>

<nav>
    <a href="main-episode-list">Main Episode List</a>
    <a href="episode-search">Search</a>
    <a href="new-episode">Add Episode</a>
</nav>

@Body

<div>
    @TrademarkMessage
</div>

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

<h1>Doctor Who™ Episode Database</h1>

<nav>
    <a href="main-episode-list">Main Episode List</a>
    <a href="episode-search">Search</a>
    <a href="new-episode">Add Episode</a>
</nav>

@Body

<div>
    @TrademarkMessage
</div>

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

<h1>Doctor Who™ Episode Database</h1>

<nav>
    <a href="main-episode-list">Main Episode List</a>
    <a href="episode-search">Search</a>
    <a href="new-episode">Add Episode</a>
</nav>

@Body

<div>
    @TrademarkMessage
</div>

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

O componente ProductionsLayout contém os elementos de layout de nível superior, em que os elementos de cabeçalho (<header>...</header>) e rodapé (<footer>...</footer>) agora residem. O DoctorWhoLayout com o componente Episodes é renderizado onde @Body aparece.

ProductionsLayout.razor:

@inherits LayoutComponentBase

<header>
    <h1>Productions</h1>
</header>

<nav>
    <a href="main-production-list">Main Production List</a>
    <a href="production-search">Search</a>
    <a href="new-production">Add Production</a>
</nav>

@Body

<footer>
    Footer of Productions Layout
</footer>
@inherits LayoutComponentBase

<header>
    <h1>Productions</h1>
</header>

<nav>
    <a href="main-production-list">Main Production List</a>
    <a href="production-search">Search</a>
    <a href="new-production">Add Production</a>
</nav>

@Body

<footer>
    Footer of Productions Layout
</footer>
@inherits LayoutComponentBase

<header>
    <h1>Productions</h1>
</header>

<nav>
    <a href="main-production-list">Main Production List</a>
    <a href="production-search">Search</a>
    <a href="new-production">Add Production</a>
</nav>

@Body

<footer>
    Footer of Productions Layout
</footer>
@inherits LayoutComponentBase

<header>
    <h1>Productions</h1>
</header>

<nav>
    <a href="main-production-list">Main Production List</a>
    <a href="production-search">Search</a>
    <a href="new-production">Add Production</a>
</nav>

@Body

<footer>
    Footer of Productions Layout
</footer>
@inherits LayoutComponentBase

<header>
    <h1>Productions</h1>
</header>

<nav>
    <a href="main-production-list">Main Production List</a>
    <a href="production-search">Search</a>
    <a href="new-production">Add Production</a>
</nav>

@Body

<footer>
    Footer of Productions Layout
</footer>
@inherits LayoutComponentBase

<header>
    <h1>Productions</h1>
</header>

<nav>
    <a href="main-production-list">Main Production List</a>
    <a href="production-search">Search</a>
    <a href="new-production">Add Production</a>
</nav>

@Body

<footer>
    Footer of Productions Layout
</footer>

A marcação HTML renderizada a seguir é produzida pelo layout aninhado anterior. A marcação desnecessária não aparece com o objetivo de focar no conteúdo embutido fornecido pelos três componentes envolvidos.

  • Os elementos de cabeçalho (<header>...</header>), barra de navegação de produção (<nav>...</nav>) e rodapé (<footer>...</footer>) e seu conteúdo são derivados do componente ProductionsLayout.
  • O título H1 do "banco de dados" (<h1>...</h1>), a barra de navegação de episódios (<nav>...</nav>) e as informações de marca registrada (<div>...</div>) vêm do componente DoctorWhoLayout.
  • O título H2 "episódios" (<h2>...</h2>) e a lista de episódios (<ul>...</ul>) são derivados do componente Episodes.
<header>
    ...
</header>

<nav>
    <a href="main-production-list">Main Production List</a>
    <a href="production-search">Search</a>
    <a href="new-production">Add Production</a>
</nav>

<h1>...</h1>

<nav>
    <a href="main-episode-list">Main Episode List</a>
    <a href="episode-search">Search</a>
    <a href="new-episode">Add Episode</a>
</nav>

<h2>...</h2>

<ul>
    <li>...</li>
    <li>...</li>
    <li>...</li>
</ul>

<div>
    ...
</div>

<footer>
    ...
</footer>

Compartilhar um layout do Razor Pages com componentes integrados

Quando componentes roteáveis são integrados a um aplicativo Razor Pages, o layout compartilhado do aplicativo pode ser usado com os componentes. Para obter mais informações, consulte Integrar ASP.NET componentes principais Razor ao MVC ou Razor ao Pages.

Seções

Para controlar o conteúdo em um layout a partir de um componente-filho Razor, consulte as seções ASP.NET Core Blazor.

Recursos adicionais