Condividi tramite


layout ASP.NET Core Blazor

Nota

Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 9 di questo articolo.

Avviso

Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere i criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 9 di questo articolo.

Importante

Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.

Per la versione corrente, vedere la versione .NET 9 di questo articolo.

Questo articolo illustra come creare componenti di layout riutilizzabili per Blazor le app.

Utilità dei Blazor layout

Alcuni elementi dell'app, ad esempio menu, messaggi di copyright e logo aziendali, fanno in genere parte della presentazione complessiva dell'app. L'inserimento di una copia del markup per questi elementi in tutti i componenti di un'app non è efficiente. Ogni volta che uno di questi elementi viene aggiornato, ogni componente che utilizza l'elemento deve essere aggiornato. Questo approccio è costoso da gestire e può causare contenuti incoerenti se un aggiornamento non è stato eseguito. I layout risolvono questi problemi.

Un Blazor layout è un Razor componente che condivide il markup con i componenti che vi fanno riferimento. I layout possono usare il data binding, l'inserimento delle dipendenze e altre funzionalità dei componenti.

Layout componenti

Creare un componente di layout

Per creare un componente di layout:

  • Creare un Razor componente definito da un modello o da codice Razor C#. I componenti di layout basati su un Razor modello usano l'estensione .razor di file esattamente come i componenti ordinari Razor . Poiché i componenti di layout vengono condivisi tra i componenti di un'app, vengono in genere inseriti nella cartella o Layout dell'appShared. Tuttavia, i layout possono essere posizionati in qualsiasi posizione accessibile ai componenti che lo usano. Ad esempio, un layout può essere inserito nella stessa cartella dei componenti che lo usano.
  • Ereditare il componente da LayoutComponentBase. LayoutComponentBase Definisce una Body proprietà (RenderFragment tipo) per il contenuto sottoposto a rendering all'interno del layout.
  • Usare la Razor sintassi @Body per specificare il percorso nel markup di layout in cui viene eseguito il rendering del contenuto.

Nota

Per altre informazioni su RenderFragment, vedere ASP.NET Componenti di baseRazor.

Il componente seguente DoctorWhoLayout mostra il Razor modello di un componente di layout. Il layout eredita LayoutComponentBase e imposta l'oggetto @Body tra la barra di spostamento (<nav>...</nav>) e il piè di pagina (<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

In un'app creata da un Blazor modello di progetto, il MainLayout componente è il layout predefinito dell'app. BlazorIl layout adotta la Flexbox layout model (MDN documentation) (specifica W3C).

BlazorLa funzionalità di isolamento CSS applica stili CSS isolati al MainLayout componente. Per convenzione, gli stili vengono forniti dal foglio di stile a fianco con lo stesso nome, MainLayout.razor.css. L'implementazione del framework ASP.NET Core del foglio di stile è disponibile per l'ispezione nell'origine di riferimento ASP.NET Core (dotnet/aspnetcore repository GitHub):

Nota

I collegamenti della documentazione all'origine del riferimento .NET in genere caricano il ramo predefinito del repository, che rappresenta lo sviluppo corrente per la versione successiva di .NET. Per selezionare un tag per una versione specifica, usare l'elenco a discesa Switch branches or tags. Per altre informazioni, vedere How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Come selezionare un tag di versione del codice sorgente di ASP.NET - dotnet/AspNetCore.Docs #26205).

BlazorLa funzionalità di isolamento CSS applica stili CSS isolati al MainLayout componente. Per convenzione, gli stili vengono forniti dal foglio di stile a fianco con lo stesso nome, MainLayout.razor.css.

Applicare un layout

Rendere disponibile lo spazio dei nomi del layout

I percorsi e gli spazi dei nomi dei file di layout sono stati modificati nel tempo per il Blazor framework. A seconda della versione di Blazor e del tipo di Blazor app che si sta creando, potrebbe essere necessario indicare lo spazio dei nomi del layout quando lo si usa. Quando si fa riferimento a un'implementazione del layout e il layout non viene trovato senza indicare lo spazio dei nomi del layout, adottare uno degli approcci seguenti:

  • Aggiungere una @using direttiva al _Imports.razor file per il percorso dei layout. Nell'esempio seguente una cartella di layout con il nome Layout si trova all'interno di una Components cartella e lo spazio dei nomi dell'app è BlazorSample:

    @using BlazorSample.Components.Layout
    
  • Aggiungere una @using direttiva nella parte superiore della definizione del componente in cui viene usato il layout:

    @using BlazorSample.Components.Layout
    @layout DoctorWhoLayout
    
  • Qualificare completamente lo spazio dei nomi del layout in cui viene usato:

    @layout BlazorSample.Components.Layout.DoctorWhoLayout
    

Applicare un layout a un componente

Utilizzare la @layoutRazor direttiva per applicare un layout a un componente instradabile Razor con una @page direttiva . Il compilatore converte @layout in e LayoutAttribute applica l'attributo alla classe component.

Il contenuto del componente seguente Episodes viene inserito nell'oggetto DoctorWhoLayout nella posizione di @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>

Il markup HTML sottoposto a rendering seguente viene prodotto dal componente e Episodes precedenteDoctorWhoLayout. Il markup estraneo non viene visualizzato per concentrarsi sul contenuto fornito dai due componenti coinvolti:

  • L'intestazione H1 "database" (<h1>...</h1>) nell'intestazione (<header>...</header>), la barra di spostamento (<nav>...</nav>) e le informazioni sul marchio nel piè di pagina (<footer>...</footer>) provengono dal DoctorWhoLayout componente.
  • Il titolo H2 "episodi" (<h2>...</h2>) e l'elenco degli episodi (<ul>...</ul>) provengono dal Episodes componente.
<header>
    <h1 ...>...</h1>
</header>

<nav>
    ...
</nav>

<h2>...</h2>

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

<footer>
    ...
</footer>

Se si specifica il layout direttamente in un componente, viene eseguito l'override di un layout predefinito:

Applicare un layout a una cartella di componenti

Ogni cartella di un'app può facoltativamente contenere un file modello denominato _Imports.razor. Il compilatore include le direttive specificate nel file imports in tutti i Razor modelli nella stessa cartella e in modo ricorsivo in tutte le relative sottocartelle. Pertanto, un _Imports.razor file contenente @layout DoctorWhoLayout garantisce che tutti i componenti di una cartella usino il DoctorWhoLayout componente. Non è necessario aggiungere @layout DoctorWhoLayout ripetutamente a tutti i Razor componenti (.razor) all'interno della cartella e delle sottocartelle.

_Imports.razor:

@layout DoctorWhoLayout
...

Il _Imports.razor file è simile al file _ViewImports.cshtml per Razor le visualizzazioni e le pagine , ma applicato in modo specifico ai Razor file del componente.

Specificando un layout in _Imports.razor viene eseguito l'override di un layout specificato come layout predefinito dell'app del router, descritto nella sezione seguente.

Avviso

Non aggiungere una Razor@layout direttiva al file radice_Imports.razor, che comporta un ciclo infinito di layout. Per controllare il layout predefinito dell'app, specificare il layout nel Router componente. Per altre informazioni, vedere la sezione Applicare un layout predefinito a un'app .

Nota

La @layoutRazor direttiva applica solo un layout ai componenti instradabili Razor con una @page direttiva .

Applicare un layout predefinito a un'app

Specificare il layout predefinito dell'app nel Router componente del RouteView componente. Usare il DefaultLayout parametro per impostare il tipo di layout:

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

Nell'esempio precedente il {LAYOUT} segnaposto è il layout ( ad esempio, DoctorWhoLayout se il nome del file di layout è DoctorWhoLayout.razor). Potrebbe essere necessario idenfity dello spazio dei nomi del layout a seconda della versione di .NET e del tipo di Blazor app. Per altre informazioni, vedere la sezione Rendere disponibile lo spazio dei nomi del layout.

Specificare il layout come layout predefinito nel Router componente è una procedura utile perché è possibile eseguire l'override RouteView del layout per ogni componente o per cartella, come descritto nelle sezioni precedenti di questo articolo. È consigliabile usare il Router componente per impostare il layout predefinito dell'app perché è l'approccio più generale e flessibile per l'uso dei layout.

Applicare un layout a contenuto arbitrario (LayoutView componente)

Per impostare un layout per il contenuto arbitrario Razor del modello, specificare il layout con un LayoutView componente. È possibile usare un oggetto LayoutView in qualsiasi Razor componente. Nell'esempio seguente viene impostato un componente di layout denominato ErrorLayout per il MainLayout modello del NotFound componente (<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>

Potrebbe essere necessario usare identity lo spazio dei nomi del layout a seconda della versione di .NET e del tipo di Blazor app. Per altre informazioni, vedere la sezione Rendere disponibile lo spazio dei nomi del layout.

Importante

Blazor Web Apps non usano il NotFound parametro (<NotFound>...</NotFound> markup), ma il parametro è supportato per la compatibilità con le versioni precedenti per evitare una modifica di rilievo nel framework. La pipeline middleware core ASP.NET lato server elabora le richieste nel server. Usare tecniche lato server per gestire richieste non valide. Per altre informazioni, vedere ASP.NET Modalità di rendering coreBlazor.

Nota

Con la versione di ASP.NET Core 5.0.1 e per eventuali versioni 5.x aggiuntive, il componente Router include il parametro PreferExactMatches impostato su @true. Per altre informazioni, vedere Eseguire la migrazione da ASP.NET Core 3.1 a 5.0.

Layout annidati

Un componente può fare riferimento a un layout che a sua volta fa riferimento a un altro layout. Ad esempio, i layout annidati vengono usati per creare strutture di menu multilivello.

Nell'esempio seguente viene illustrato come usare layout annidati. Il Episodes componente illustrato nella sezione Applica un layout a un componente è il componente da visualizzare. Il componente fa riferimento al DoctorWhoLayout componente.

Il componente seguente DoctorWhoLayout è una versione modificata dell'esempio illustrato in precedenza in questo articolo. Gli elementi intestazione e piè di pagina vengono rimossi e il layout fa riferimento a un altro layout, ProductionsLayout. Viene eseguito il rendering del Episodes componente in cui @Body viene visualizzato in 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/";
}

Il ProductionsLayout componente contiene gli elementi di layout di primo livello, in cui si trovano gli elementi intestazione (<header>...</header>) e piè di pagina (<footer>...</footer>). Viene eseguito il rendering dell'oggetto DoctorWhoLayout con il Episodes componente in cui @Body viene visualizzato.

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>

Il markup HTML sottoposto a rendering seguente viene prodotto dal layout annidato precedente. Il markup estraneo non viene visualizzato per concentrarsi sul contenuto annidato fornito dai tre componenti coinvolti:

  • L'intestazione (<header>...</header>), la barra di spostamento di produzione (<nav>...</nav>) e gli elementi piè di pagina (<footer>...</footer>) e il ProductionsLayout relativo contenuto provengono dal componente.
  • L'intestazione H1 "database" (<h1>...</h1>), la barra di spostamento dell'episodio () e le informazioni sul marchio (<nav>...</nav><div>...</div>) provengono dal DoctorWhoLayout componente.
  • Il titolo H2 "episodi" (<h2>...</h2>) e l'elenco degli episodi (<ul>...</ul>) provengono dal Episodes componente.
<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>

Condividere un Razor layout di pagine con componenti integrati

Quando i componenti instradabili sono integrati in un'app Razor Pages, il layout condiviso dell'app può essere usato con i componenti. Per altre informazioni, vedere Integrare ASP.NET componenti Core Razor con MVC o Razor Pages.

Sezioni

Per controllare il contenuto in un layout da un componente figlioRazor, vedere ASP.NET sezioni CoreBlazor.

Risorse aggiuntive