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 oLayout
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 nomeLayout
si trova all'interno di unaComponents
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 @layout
Razor 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 dalDoctorWhoLayout
componente. - Il titolo H2 "episodi" (
<h2>...</h2>
) e l'elenco degli episodi (<ul>...</ul>
) provengono dalEpisodes
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:
- Impostare da una
@layout
direttiva importata da un_Imports.razor
file, come descritto nella sezione Applicare un layout a una cartella di componenti . - Impostare come layout predefinito dell'app, come descritto nella sezione Applicare un layout predefinito a un'app più avanti in questo articolo.
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 @layout
Razor 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 ilProductionsLayout
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 dalDoctorWhoLayout
componente. - Il titolo H2 "episodi" (
<h2>...</h2>
) e l'elenco degli episodi (<ul>...</ul>
) provengono dalEpisodes
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.