Composants Razor ASP.NET Core
Remarque
Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 9 de cet article.
Avertissement
Cette version d’ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la stratégie de support .NET et .NET Core. Pour la version actuelle, consultez la version .NET 9 de cet article.
Important
Ces informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.
Pour la version actuelle, consultez la version .NET 9 de cet article.
Cet article explique comment créer et utiliser des composants Razor dans des applications Blazor et fournit des conseils sur la syntaxe Razor, le nommage de composants, les espaces de noms et les paramètres de composant.
Composants Razor
Les applications Blazor sont créées en utilisant Razor composants de , communément appelés composants deBlazor ou uniquement composants. Un composant est une partie autonome de l’interface utilisateur (IU), avec une logique de traitement pour prendre en charge le comportement dynamique. Les composants peuvent être imbriqués, réutilisés, partagés entre plusieurs projets et utilisés dans des applications MVC et Razor Pages.
Les composants s’affichent dans une représentation en mémoire du modèle DOM (Document Object Model) du navigateur, appelée arborescence de rendu, qui permet de mettre à jour l’IU de manière flexible et efficace.
Bien que les « composants Razor » partagent certains éléments de noms avec d’autres technologies de rendu de contenu ASP.NET Core, les composants Razor doivent être différenciés des différentes fonctionnalités suivantes dans ASP.NET Core :
- Les vues Razor, qui sont des pages de balisage basées sur Razor pour les applications MVC.
- Les composants d’affichage, qui permettent de restituer des blocs de contenu plutôt que des réponses entières dans les applications Razor Pages et MVC.
Important
Lors de l’utilisation d’une Blazor Web App, la plupart des composants de l’exemple de documentation Blazornécessitent une interactivité pour fonctionner et démontrer les concepts couverts par les articles. Lorsque vous testez un composant d’exemple fourni par un article, assurez-vous que l’application adopte une interactivité globale ou que le composant adopte un mode de rendu interactif. Plus d’informations sur ce sujet sont fournies par dans Modes de rendu ASP.NET Core Blazor, qui est l’article suivant dans la table des matières après cet article.
Classes de composant
Les composants sont implémentés en utilisant une combinaison de balises C# et HTML dans des fichiers de composants Razor avec l’extension de fichier .razor
.
ComponentBase est la classe de base pour les composants décrits par les fichiers de composants Razor. ComponentBase implémente l’abstraction la plus faible des composants, l’interface IComponent. ComponentBase définit des propriétés et des méthodes de composant pour les fonctionnalités de base, par exemple pour traiter un ensemble d’événements de cycle de vie de composant intégrés.
ComponentBase
dans la dotnet/aspnetcore
source de référence : la source de référence contient des remarques supplémentaires sur les événements de cycle de vie intégrés. Toutefois, gardez à l’esprit que les implémentations internes des fonctionnalités de composant sont susceptibles d’être modifiées à tout moment sans préavis.
Remarque
Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Les développeurs créent Razor généralement des composants à partir de fichiers de composants Razor (.razor
) ou basent leurs composants sur ComponentBase, mais les composants peuvent également être générés en implémentant IComponent. Les composants créés par le développeur qui implémentent IComponent peuvent prendre un contrôle de bas niveau sur le rendu au prix de devoir déclencher manuellement le rendu avec des événements et des méthodes de cycle de vie que le développeur doit créer et gérer.
Des conventions supplémentaires adoptées par des exemples de code de documentation Blazor et des exemples d’applications se trouvent dans Notions fondamentales Blazor ASP.NET Core.
Syntaxe de Razor
Les composants suivent la syntaxe Razor. Deux fonctionnalités Razor sont largement utilisées par les composants : les directives et les attributs de directive. Il s’agit de mots clés réservés, préfixés par @
, qui apparaissent dans le balisage Razor :
Directives : modifient le mode de compilation ou de fonctionnement du balisage d’un composant. Par exemple, la directive
@page
spécifie un composant routable avec un modèle de routage accessible directement sur demande d’un utilisateur dans le navigateur à une URL spécifique.Par convention, les directives d’un composant en haut d’une définition de composant (fichier
.razor
) sont placées dans un ordre cohérent. Pour les directives répétées, les directives sont placées par ordre alphabétique par espace de noms ou par type, à l’exception des directives@using
, qui ont un ordre spécial de second niveau.L’ordre suivant est adopté par des exemples d’applications et de documentation Blazor. Les composants fournis par un modèle de projet Blazor peuvent différer de l’ordre suivant et utiliser un autre format. Par exemple, les composants Identity du framework Blazorincluent des lignes vides entre des blocs de directives
@using
et des blocs de directives@inject
. Vous êtes libre d’utiliser un format et un schéma de classement personnalisé dans vos propres applications.Documentation et exemple d’ordre de directive d’application Razor :
@page
@rendermode
(.NET 8 ou version ultérieure)@using
- Espaces de noms de
System
(ordre alphabétique) - Espaces de noms de
Microsoft
(ordre alphabétique) - Espaces de noms d’API tiers (ordre alphabétique)
- Espaces de noms d’application (ordre alphabétique)
- Espaces de noms de
- Autres directives (ordre alphabétique)
Aucune ligne vide n’apparaît parmi les directives. Une ligne vide apparaît entre les directives et la première ligne du balisage Razor.
Exemple :
@page "/doctor-who-episodes/{season:int}" @rendermode InteractiveWebAssembly @using System.Globalization @using System.Text.Json @using Microsoft.AspNetCore.Localization @using Mandrill @using BlazorSample.Components.Layout @attribute [Authorize] @implements IAsyncDisposable @inject IJSRuntime JS @inject ILogger<DoctorWhoEpisodes> Logger <PageTitle>Doctor Who Episode List</PageTitle> ...
Attributs de directive : modifient le mode de compilation ou de fonctionnement d’un élément de composant.
Exemple :
<input @bind="episodeId" />
Vous pouvez préfixer les valeurs d’attribut de directive avec le symbole
@
pour les expressions Razor non explicites (@bind="@episodeId"
), mais nous vous le déconseillons. Par conséquent, les exemples donnés dans les documents n’adoptent pas cette approche.
Les directives et attributs de directive utilisés dans des composants sont expliqués plus loin dans cet article et dans d’autres articles de la documentation Blazor. Pour obtenir une description générale de la syntaxe Razor, consultez les informations de référence sur la syntaxe Razor pour ASP.NET Core.
Nom du composant, nom de classe et espace de noms
Le nom d’un composant doit commencer par une majuscule :
Pris en charge : ProductDetail.razor
Non pris en charge : productDetail.razor
Parmi les conventions de nommage Blazor couramment utilisées dans la documentation Blazor, citons les suivantes :
- Les chemins d’accès aux fichiers et les noms de fichiers utilisent la casse Pascal† et apparaissent avant d’afficher des exemples de code. Si un chemin d’accès est présent, il indique l’emplacement du dossier classique. Par exemple,
Components/Pages/ProductDetail.razor
indique que le composantProductDetail
a pour nom de fichierProductDetail.razor
et réside dans le dossierPages
du dossierComponents
de l’application. - Les chemins aux fichiers de composants routables correspondent à leurs URL dans le kebab case ‡ avec des tirets apparaissant entre les mots dans le modèle de routage d’un composant. Par exemple, un composant
ProductDetail
avec le modèle de routage/product-detail
(@page "/product-detail"
) est demandé dans un navigateur à l’URL relative/product-detail
.
†La casse Pascal (casse mixte avec majuscules) est une convention de nommage sans espaces ni ponctuation où la première lettre de chaque mot est en majuscule, y compris le premier mot.
La casse kebab est une convention d’affectation de noms sans espaces et ponctuation qui utilise des lettres minuscules et des tirets entre les mots.
Les composants sont des classes C# ordinaires que vous pouvez placer n’importe où dans un projet. Les composants qui produisent des pages web résident généralement dans le dossier Components/Pages
. Les composants autres que des pages sont fréquemment placés dans le dossier Components
ou dans un dossier personnalisé ajouté au projet.
En général, l’espace de noms d’un composant est dérivé de l’espace de noms racine de l’application et de l’emplacement (dossier) du composant dans l’application. Si l’espace de noms racine de l’application est BlazorSample
et que le composant Counter
réside dans le dossier Components/Pages
:
- L’espace de noms du composant
Counter
estBlazorSample.Components.Pages
. - Le nom de type complet du composant est
BlazorSample.Components.Pages.Counter
.
Pour les dossiers personnalisés contenant des composants, ajoutez une directive @using
au composant parent ou au fichier _Imports.razor
de l’application. L’exemple suivant rend les composants du dossier AdminComponents
disponibles :
@using BlazorSample.AdminComponents
Remarque
Les directives @using
dans le fichier _Imports.razor
ne s’appliquent qu’aux fichiers Razor (.razor
), pas aux fichiers C# (.cs
).
Les instructions alias using
sont prises en charge. Dans l’exemple suivant, la classe publique WeatherForecast
du composantGridRendering
est rendue disponible comme WeatherForecast
dans un composant situé ailleurs dans l’application :
@using WeatherForecast = Components.Pages.GridRendering.WeatherForecast
Vous pouvez également référencer des composants avec leurs noms complets, ce qui ne nécessite pas de directive @using
. L’exemple suivant référence directement le composant ProductDetail
dans le dossier AdminComponents/Pages
de l’application :
<BlazorSample.AdminComponents.Pages.ProductDetail />
L’espace de noms d’un composant créé avec Razor est basé sur les éléments suivants (par ordre de priorité) :
- Directive
@namespace
dans le balisage du fichier Razor (par exemple,@namespace BlazorSample.CustomNamespace
). RootNamespace
du projet dans le fichier de projet (par exemple,<RootNamespace>BlazorSample</RootNamespace>
).- Les Espace de noms du projet et chemin d’accès de la racine du projet au composant. Par exemple, le framework résout
{PROJECT NAMESPACE}/Components/Pages/Home.razor
avec l’espace de noms de projetBlazorSample
en espace de nomsBlazorSample.Components.Pages
pour le composantHome
.{PROJECT NAMESPACE}
est l’espace de noms du projet. Les composants suivent les règles de liaison de nom C#. Pour le composantHome
de cet exemple, les composants dans l’étendue sont tous les composants :- Dans le même dossier,
Components/Pages
. - Composants à la racine du projet qui ne spécifient pas explicitement un autre espace de noms.
- Dans le même dossier,
Les éléments suivants ne sont pas pris en charge :
- Qualification
global::
. - Noms partiellement qualifiés. Par exemple, vous ne pouvez pas ajouter
@using BlazorSample.Components
à un composant, puis référencer le composantNavMenu
dans le dossierComponents/Layout
de l’application (Components/Layout/NavMenu.razor
) avec<Layout.NavMenu></Layout.NavMenu>
.
Le nom d’un composant doit commencer par une majuscule :
Pris en charge : ProductDetail.razor
Non pris en charge : productDetail.razor
Parmi les conventions de nommage Blazor couramment utilisées dans la documentation Blazor, citons les suivantes :
- Les chemins d’accès aux fichiers et les noms de fichiers utilisent la casse Pascal† et apparaissent avant d’afficher des exemples de code. Si un chemin d’accès est présent, il indique l’emplacement du dossier classique. Par exemple,
Pages/ProductDetail.razor
indique que le composantProductDetail
a pour nom de fichierProductDetail.razor
et réside dans le dossierPages
de l’application. - Les chemins aux fichiers de composants routables correspondent à leurs URL dans le kebab case ‡ avec des tirets apparaissant entre les mots dans le modèle de routage d’un composant. Par exemple, un composant
ProductDetail
avec le modèle de routage/product-detail
(@page "/product-detail"
) est demandé dans un navigateur à l’URL relative/product-detail
.
†La casse Pascal (casse mixte avec majuscules) est une convention de nommage sans espaces ni ponctuation où la première lettre de chaque mot est en majuscule, y compris le premier mot.
La casse kebab est une convention d’affectation de noms sans espaces et ponctuation qui utilise des lettres minuscules et des tirets entre les mots.
Les composants sont des classes C# ordinaires que vous pouvez placer n’importe où dans un projet. Les composants qui produisent des pages web résident généralement dans le dossier Pages
. Les composants autres que des pages sont fréquemment placés dans le dossier Shared
ou dans un dossier personnalisé ajouté au projet.
En général, l’espace de noms d’un composant est dérivé de l’espace de noms racine de l’application et de l’emplacement (dossier) du composant dans l’application. Si l’espace de noms racine de l’application est BlazorSample
et que le composant Counter
réside dans le dossier Pages
:
- L’espace de noms du composant
Counter
estBlazorSample.Pages
. - Le nom de type complet du composant est
BlazorSample.Pages.Counter
.
Pour les dossiers personnalisés contenant des composants, ajoutez une directive @using
au composant parent ou au fichier _Imports.razor
de l’application. L’exemple suivant rend les composants du dossier AdminComponents
disponibles :
@using BlazorSample.AdminComponents
Remarque
Les directives @using
dans le fichier _Imports.razor
ne s’appliquent qu’aux fichiers Razor (.razor
), pas aux fichiers C# (.cs
).
Les instructions alias using
sont prises en charge. Dans l’exemple suivant, la classe publique WeatherForecast
du composantGridRendering
est rendue disponible comme WeatherForecast
dans un composant situé ailleurs dans l’application :
@using WeatherForecast = Pages.GridRendering.WeatherForecast
Vous pouvez également référencer des composants avec leurs noms complets, ce qui ne nécessite pas de directive @using
. L’exemple suivant référence directement le composant ProductDetail
dans le dossier Components
de l’application :
<BlazorSample.Components.ProductDetail />
L’espace de noms d’un composant créé avec Razor est basé sur les éléments suivants (par ordre de priorité) :
- Directive
@namespace
dans le balisage du fichier Razor (par exemple,@namespace BlazorSample.CustomNamespace
). RootNamespace
du projet dans le fichier de projet (par exemple,<RootNamespace>BlazorSample</RootNamespace>
).- Les Espace de noms du projet et chemin d’accès de la racine du projet au composant. Par exemple, le framework résout
{PROJECT NAMESPACE}/Pages/Index.razor
avec l’espace de noms de projetBlazorSample
en espace de nomsBlazorSample.Pages
pour le composantIndex
.{PROJECT NAMESPACE}
est l’espace de noms du projet. Les composants suivent les règles de liaison de nom C#. Pour le composantIndex
de cet exemple, les composants dans l’étendue sont tous les composants :- Dans le même dossier,
Pages
. - Composants à la racine du projet qui ne spécifient pas explicitement un autre espace de noms.
- Dans le même dossier,
Les éléments suivants ne sont pas pris en charge :
- Qualification
global::
. - Noms partiellement qualifiés. Par exemple, vous ne pouvez pas ajouter
@using BlazorSample
à un composant, puis référencer le composantNavMenu
dans le dossierShared
de l’application (Shared/NavMenu.razor
) avec<Shared.NavMenu></Shared.NavMenu>
.
Prise en charge de classes partielles
Les composants sont générés en tant que classes partielles C# et sont créés à l’aide de l’une des approches suivantes :
- Un seul fichier contient du code C# défini dans un ou plusieurs blocs
@code
, un balisage HTML et un balisage Razor. Les modèles de projet Blazor définissent leurs composants à l’aide de cette approche monofichier. - Les balisages HTML et Razor sont placés dans un fichier Razor (
.razor
). Le code C# est placé dans un fichier code-behind défini en tant que classe partielle (.cs
).
Remarque
Une feuille de style de composant qui définit des styles spécifiques aux composants est un fichier distinct (.css
). L’isolation CSS Blazor est décrite plus loin dans Isolation CSS dans Blazor ASP.NET Core.
L’exemple suivant montre le composant Counter
par défaut avec un bloc @code
dans une application générée à partir d’un modèle de projet Blazor. Le balisage et le code C# sont dans le même fichier. Il s’agit de l’approche la plus couramment adoptée pour créer des composants.
Counter.razor
:
@page "/counter"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount() => currentCount++;
}
@page "/counter"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount() => currentCount++;
}
@page "/counter"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
@page "/counter"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
@page "/counter"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
@page "/counter"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
Le composant Counter
suivant sépare le balisage de la présentation HTML et le Razor du code C# en utilisant un fichier code-behind avec une classe partielle. Le fractionnement du balisage du code C# est privilégié par certaines organisations et développeurs pour organiser leur code de composant en fonction de leur mode de travail. Par exemple, l’expert en interface utilisateur de l’organisation peut travailler sur la couche de présentation indépendamment d’un autre développeur sui travaille sur la logique C# du composant. L’approche est également utile lors de l’utilisation de générateurs de code ou de sources générés automatiquement. Pour plus d’informations, consultez Classes et méthodes partielles (Guide de programmation C#).
CounterPartialClass.razor
:
@page "/counter-partial-class"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@page "/counter-partial-class"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@page "/counter-partial-class"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@page "/counter-partial-class"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@page "/counter-partial-class"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@page "/counter-partial-class"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
CounterPartialClass.razor.cs
:
namespace BlazorSample.Components.Pages;
public partial class CounterPartialClass
{
private int currentCount = 0;
private void IncrementCount() => currentCount++;
}
namespace BlazorSample.Components.Pages;
public partial class CounterPartialClass
{
private int currentCount = 0;
private void IncrementCount() => currentCount++;
}
namespace BlazorSample.Pages;
public partial class CounterPartialClass
{
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
namespace BlazorSample.Pages
{
public partial class CounterPartialClass
{
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
}
Les directives @using
dans le fichier _Imports.razor
ne s’appliquent qu’aux fichiers Razor (.razor
), pas aux fichiers C# (.cs
). Ajoutez des espaces de noms à un fichier de classe partielle en fonction des besoins.
Espaces de noms standard utilisés par les composants :
using System.Net.Http;
using System.Net.Http.Json;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.Sections
using Microsoft.AspNetCore.Components.Web;
using static Microsoft.AspNetCore.Components.Web.RenderMode;
using Microsoft.AspNetCore.Components.Web.Virtualization;
using Microsoft.JSInterop;
Les espaces de noms standard incluent également l’espace de noms de l’application et l’espace de noms correspondant au dossier Components
de l’application :
using BlazorSample;
using BlazorSample.Components;
Des dossiers supplémentaires peuvent également être inclus, tels que le dossier Layout
:
using BlazorSample.Components.Layout;
using System.Net.Http;
using System.Net.Http.Json;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.Web.Virtualization;
using Microsoft.JSInterop;
Les espaces de noms standard incluent également l’espace de noms de l’application et l’espace de noms correspondant au dossier Shared
de l’application :
using BlazorSample;
using BlazorSample.Shared;
using System.Net.Http;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.JSInterop;
Les espaces de noms standard incluent également l’espace de noms de l’application et l’espace de noms correspondant au dossier Shared
de l’application :
using BlazorSample;
using BlazorSample.Shared;
Spécifier une classe de base
La directive @inherits
est utilisée pour spécifier la classe de base d’un composant. Contrairement à l’utilisation de classes partielles, qui fractionne uniquement le balisage de la logique C#, l’utilisation d’une classe de base vous permet d’hériter du code C# pour une utilisation dans un groupe de composants qui partagent les propriétés et méthodes de la classe de base. L’utilisation de classes de base réduit la redondance du code dans les applications et est utile lorsque vous fournissez du code de base des bibliothèques de classes à plusieurs applications. Pour plus d’informations, consultez Héritage en C# et .NET.
Dans l’exemple suivant, la classe de base BlazorRocksBase1
dérive de ComponentBase.
BlazorRocks1.razor
:
@page "/blazor-rocks-1"
@inherits BlazorRocksBase1
<PageTitle>Blazor Rocks!</PageTitle>
<h1>Blazor Rocks! Example 1</h1>
<p>
@BlazorRocksText
</p>
@page "/blazor-rocks-1"
@inherits BlazorRocksBase1
<PageTitle>Blazor Rocks!</PageTitle>
<h1>Blazor Rocks! Example 1</h1>
<p>
@BlazorRocksText
</p>
@page "/blazor-rocks-1"
@inherits BlazorRocksBase1
<PageTitle>Blazor Rocks!</PageTitle>
<h1>Blazor Rocks! Example 1</h1>
<p>
@BlazorRocksText
</p>
@page "/blazor-rocks-1"
@inherits BlazorRocksBase1
<PageTitle>Blazor Rocks!</PageTitle>
<h1>Blazor Rocks! Example 1</h1>
<p>
@BlazorRocksText
</p>
@page "/blazor-rocks-1"
@inherits BlazorRocksBase1
<h1>Blazor Rocks! Example 1</h1>
<p>
@BlazorRocksText
</p>
@page "/blazor-rocks-1"
@inherits BlazorRocksBase1
<h1>Blazor Rocks! Example 1</h1>
<p>
@BlazorRocksText
</p>
BlazorRocksBase1.cs
:
using Microsoft.AspNetCore.Components;
namespace BlazorSample;
public class BlazorRocksBase1 : ComponentBase
{
public string BlazorRocksText { get; set; } = "Blazor rocks the browser!";
}
using Microsoft.AspNetCore.Components;
namespace BlazorSample;
public class BlazorRocksBase1 : ComponentBase
{
public string BlazorRocksText { get; set; } = "Blazor rocks the browser!";
}
using Microsoft.AspNetCore.Components;
namespace BlazorSample;
public class BlazorRocksBase1 : ComponentBase
{
public string BlazorRocksText { get; set; } =
"Blazor rocks the browser!";
}
using Microsoft.AspNetCore.Components;
namespace BlazorSample;
public class BlazorRocksBase1 : ComponentBase
{
public string BlazorRocksText { get; set; } =
"Blazor rocks the browser!";
}
using Microsoft.AspNetCore.Components;
namespace BlazorSample;
public class BlazorRocksBase1 : ComponentBase
{
public string BlazorRocksText { get; set; } =
"Blazor rocks the browser!";
}
using Microsoft.AspNetCore.Components;
namespace BlazorSample;
public class BlazorRocksBase1 : ComponentBase
{
public string BlazorRocksText { get; set; } =
"Blazor rocks the browser!";
}
Routage
Pour router dans Blazor, un modèle de routage est fourni à chaque composant accessible dans l’application avec une directive @page
. Quand un fichier Razor avec une directive @page
est compilé, la classe générée reçoit un RouteAttribute spécifiant le modèle de routage. Au moment de l’exécution, le routeur recherche les classes de composant avec un RouteAttribute et génère le rendu du composant dont le modèle de routage correspond à l’URL demandée.
Le composant suivant HelloWorld
utilise un modèle d’itinéraire de /hello-world
, et la page web rendue pour le composant est atteinte à l’URL /hello-world
relative.
HelloWorld.razor
:
@page "/hello-world"
<PageTitle>Hello World!</PageTitle>
<h1>Hello World!</h1>
@page "/hello-world"
<PageTitle>Hello World!</PageTitle>
<h1>Hello World!</h1>
@page "/hello-world"
<h1>Hello World!</h1>
@page "/hello-world"
<h1>Hello World!</h1>
@page "/hello-world"
<h1>Hello World!</h1>
@page "/hello-world"
<h1>Hello World!</h1>
Le composant précédent se charge dans le navigateur à l’adresse /hello-world
, que vous ajoutiez ou non le composant à la navigation de l’interface utilisateur de l’application. Si vous le souhaitez, vous pouvez ajouter un composant au composant NavMenu
pour faire apparaître un lien vers le composant dans la navigation basée sur l’interface utilisateur de l’application.
Pour le composant HelloWorld
précédent, vous pouvez ajouter un composant NavLink
au composant NavMenu
. Pour obtenir plus d’informations, notamment les descriptions des composants NavLink
et NavMenu
, consultez Routage et navigation dans Blazor ASP.NET Core.
balisage
L’interface utilisateur d’un composant est définie à l’aide de la syntaxe Razor, qui comprend le balisage Razor et du code C# et HTML. Quand une application est compilée, le balisage HTML et la logique de rendu C# sont convertis en classe de composant. Le nom de la classe générée correspond au nom du fichier.
Les membres de la classe de composant sont définis dans un ou plusieurs blocs @code
. Dans les blocs @code
, l’état du composant est spécifié et traité avec C# :
- Initialiseurs de propriété et de champ.
- Valeurs de paramètre à partir d’arguments passés par les composants parents et les paramètres de routage.
- Méthodes de gestion des événements utilisateur, des événements de cycle de vie et de la logique des composants personnalisés.
Les membres d’un composant sont utilisés dans la logique de rendu au moyen d’expressions C# qui commencent par le symbole @
. Par exemple, un champ C# est rendu en préfixant @
au nom du champ. Le composant Markup
suivant évalue ce qui suit et en génère le rendu :
headingFontStyle
pour la valeur de propriété CSSfont-style
de l’élément de titre.headingText
pour le contenu de l’élément de titre.
Markup.razor
:
@page "/markup"
<PageTitle>Markup</PageTitle>
<h1>Markup Example</h1>
<h2 style="font-style:@headingFontStyle">@headingText</h2>
@code {
private string headingFontStyle = "italic";
private string headingText = "Put on your new Blazor!";
}
@page "/markup"
<PageTitle>Markup</PageTitle>
<h1>Markup Example</h1>
<h2 style="font-style:@headingFontStyle">@headingText</h2>
@code {
private string headingFontStyle = "italic";
private string headingText = "Put on your new Blazor!";
}
@page "/markup"
<h1 style="font-style:@headingFontStyle">@headingText</h1>
@code {
private string headingFontStyle = "italic";
private string headingText = "Put on your new Blazor!";
}
@page "/markup"
<h1 style="font-style:@headingFontStyle">@headingText</h1>
@code {
private string headingFontStyle = "italic";
private string headingText = "Put on your new Blazor!";
}
@page "/markup"
<h1 style="font-style:@headingFontStyle">@headingText</h1>
@code {
private string headingFontStyle = "italic";
private string headingText = "Put on your new Blazor!";
}
@page "/markup"
<h1 style="font-style:@headingFontStyle">@headingText</h1>
@code {
private string headingFontStyle = "italic";
private string headingText = "Put on your new Blazor!";
}
Remarque
Les exemples fournis dans la documentation Blazor spécifient le modificateur d’accès private
pour les membres privés. Les membres privés sont délimités à la classe d’un composant. Cependant, C# opte pour le modificateur d’accès private
quand aucun modificateur d’accès n’est présent. Vous n’êtes donc pas obligé de marquer explicitement les membres avec « private
». Pour plus d’informations sur les modificateurs d’accès, consultez Modificateurs d’accès (Guide de programmation C#).
Le framework Blazor traite un composant en interne comme une arborescence de rendu, qui est la combinaison du DOM et du modèle de l’objet CSSOM (Cascading Style Sheet Object Model). Après le rendu initial du composant, son arborescence de rendu est regénérée en réponse aux événements. Blazor compare la nouvelle arborescence de rendu à la précédente et applique toute modification apportée au modèle DOM du navigateur pour affichage. Pour plus d’informations, consultez le rendu de composants Razor ASP.NET Core.
Dans la syntaxe Razor, les structures de contrôle, directives et attributs de directive C# sont en minuscules (exemples : @if
, @code
, @bind
). Les noms de propriété sont en majuscules (exemple : @Body
pour LayoutComponentBase.Body).
Les méthodes asynchrones (async
) ne prennent pas en charge void
en retour
Le framework Blazor ne suit pas les méthodes asynchrones retournant void
(async
). Par conséquent, les exceptions ne sont pas interceptées si void
est retourné. Retournez toujours une Task à partir de méthodes asynchrones.
Composants imbriqués
Les composants peuvent inclure d’autres composants en les déclarant avec la syntaxe HTML. Le balisage pour l’utilisation d’un composant ressemble à une balise HTML où le nom de la balise est le type du composant.
Considérez le composant Heading
suivant, qui peut être utilisé par d’autres composants pour afficher un titre.
Heading.razor
:
<h1 style="font-style:@headingFontStyle">Heading Example</h1>
@code {
private string headingFontStyle = "italic";
}
<h1 style="font-style:@headingFontStyle">Heading Example</h1>
@code {
private string headingFontStyle = "italic";
}
<h1 style="font-style:@headingFontStyle">Heading Example</h1>
@code {
private string headingFontStyle = "italic";
}
<h1 style="font-style:@headingFontStyle">Heading Example</h1>
@code {
private string headingFontStyle = "italic";
}
<h1 style="font-style:@headingFontStyle">Heading Example</h1>
@code {
private string headingFontStyle = "italic";
}
<h1 style="font-style:@headingFontStyle">Heading Example</h1>
@code {
private string headingFontStyle = "italic";
}
Le balisage suivant dans le composant HeadingExample
génère le rendu du composant Heading
précédent à l’emplacement où la balise <Heading />
apparaît.
HeadingExample.razor
:
@page "/heading-example"
<PageTitle>Heading</PageTitle>
<h1>Heading Example</h1>
<Heading />
@page "/heading-example"
<PageTitle>Heading</PageTitle>
<h1>Heading Example</h1>
<Heading />
@page "/heading-example"
<Heading />
@page "/heading-example"
<Heading />
@page "/heading-example"
<Heading />
@page "/heading-example"
<Heading />
Si un composant contient un élément HTML avec une première lettre majuscule qui ne correspond pas à un nom de composant dans le même espace de noms, un avertissement est émis indiquant que l’élément a un nom inattendu. L’ajout d’une directive @using
pour l’espace de noms du composant rend le composant disponible, ce qui résout l’avertissement. Pour plus d’informations, consultez la section Nom du composant, nom de la classe et espace de noms.
L’exemple de composant Heading
présenté dans cette section n’ayant pas de directive @page
, un utilisateur ne peut pas accéder directement au composant Heading
par le biais d’une demande directe dans le navigateur. Toutefois, tout composant avec une directive @page
peut être imbriqué dans un autre composant. Si l’ajout de @page "/heading"
en haut du fichier Razor du composant Heading
le rend directement accessible, le composant est alors rendu pour les demandes de navigateur aux emplacements /heading
et /heading-example
.
Paramètres de composant
Les paramètres de composant passent les données aux composants et sont définis à l’aide de propriétés C# publiques sur la classe de composant avec l’attribut [Parameter]
. Dans l’exemple suivant, un type de référence intégré (System.String) et un type de référence défini par l’utilisateur (PanelBody
) sont passés en tant que paramètres de composant.
PanelBody.cs
:
namespace BlazorSample;
public class PanelBody
{
public string? Text { get; set; }
public string? Style { get; set; }
}
namespace BlazorSample;
public class PanelBody
{
public string? Text { get; set; }
public string? Style { get; set; }
}
public class PanelBody
{
public string? Text { get; set; }
public string? Style { get; set; }
}
public class PanelBody
{
public string? Text { get; set; }
public string? Style { get; set; }
}
public class PanelBody
{
public string Text { get; set; }
public string Style { get; set; }
}
public class PanelBody
{
public string Text { get; set; }
public string Style { get; set; }
}
ParameterChild.razor
:
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">@Title</div>
<div class="card-body" style="font-style:@Body.Style">
@Body.Text
</div>
</div>
@code {
[Parameter]
public string Title { get; set; } = "Set By Child";
[Parameter]
public PanelBody Body { get; set; } =
new()
{
Text = "Card content set by child.",
Style = "normal"
};
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">@Title</div>
<div class="card-body" style="font-style:@Body.Style">
@Body.Text
</div>
</div>
@code {
[Parameter]
public string Title { get; set; } = "Set By Child";
[Parameter]
public PanelBody Body { get; set; } =
new()
{
Text = "Card content set by child.",
Style = "normal"
};
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">@Title</div>
<div class="card-body" style="font-style:@Body.Style">
@Body.Text
</div>
</div>
@code {
[Parameter]
public string Title { get; set; } = "Set By Child";
[Parameter]
public PanelBody Body { get; set; } =
new()
{
Text = "Set by child.",
Style = "normal"
};
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">@Title</div>
<div class="card-body" style="font-style:@Body.Style">
@Body.Text
</div>
</div>
@code {
[Parameter]
public string Title { get; set; } = "Set By Child";
[Parameter]
public PanelBody Body { get; set; } =
new()
{
Text = "Set by child.",
Style = "normal"
};
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">@Title</div>
<div class="card-body" style="font-style:@Body.Style">
@Body.Text
</div>
</div>
@code {
[Parameter]
public string Title { get; set; } = "Set By Child";
[Parameter]
public PanelBody Body { get; set; } =
new()
{
Text = "Set by child.",
Style = "normal"
};
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">@Title</div>
<div class="card-body" style="font-style:@Body.Style">
@Body.Text
</div>
</div>
@code {
[Parameter]
public string Title { get; set; } = "Set By Child";
[Parameter]
public PanelBody Body { get; set; } =
new PanelBody()
{
Text = "Set by child.",
Style = "normal"
};
}
Warning
La spécification de valeurs initiales pour les paramètres de composant est prise en charge, mais ne créez pas de composant qui écrit dans ses propres paramètres après le rendu initial du composant. Pour plus d’informations, consultez Éviter le remplacement de paramètres dans ASP.NET Core Blazor.
Les paramètres de composant Title
et Body
du composant ParameterChild
sont définis par des arguments dans la balise HTML qui génère le rendu de l’instance du composant. Le composant ParameterParent
suivant génère le rendu de deux composants ParameterChild
:
- Le premier composant
ParameterChild
est rendu sans fournir d’arguments de paramètre. - Le deuxième composant
ParameterChild
reçoit des valeurs pourTitle
etBody
du composantParameterParent
, qui utilise une expression C# explicite pour définir les valeurs des propriétés dePanelBody
.
Parameter1.razor
:
@page "/parameter-1"
<PageTitle>Parameter 1</PageTitle>
<h1>Parameter Example 1</h1>
<h1>Child component (without attribute values)</h1>
<ParameterChild />
<h1>Child component (with attribute values)</h1>
<ParameterChild Title="Set by Parent"
Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" />
Parameter1.razor
:
@page "/parameter-1"
<PageTitle>Parameter 1</PageTitle>
<h1>Parameter Example 1</h1>
<h1>Child component (without attribute values)</h1>
<ParameterChild />
<h1>Child component (with attribute values)</h1>
<ParameterChild Title="Set by Parent"
Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" />
ParameterParent.razor
:
@page "/parameter-parent"
<h1>Child component (without attribute values)</h1>
<ParameterChild />
<h1>Child component (with attribute values)</h1>
<ParameterChild Title="Set by Parent"
Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" />
ParameterParent.razor
:
@page "/parameter-parent"
<h1>Child component (without attribute values)</h1>
<ParameterChild />
<h1>Child component (with attribute values)</h1>
<ParameterChild Title="Set by Parent"
Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" />
ParameterParent.razor
:
@page "/parameter-parent"
<h1>Child component (without attribute values)</h1>
<ParameterChild />
<h1>Child component (with attribute values)</h1>
<ParameterChild Title="Set by Parent"
Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" />
ParameterParent.razor
:
@page "/parameter-parent"
<h1>Child component (without attribute values)</h1>
<ParameterChild />
<h1>Child component (with attribute values)</h1>
<ParameterChild Title="Set by Parent"
Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" />
Le balisage HTML rendu suivant du composant ParameterParent
montre les valeurs par défaut du composant ParameterChild
quand le composant ParameterParent
ne fournit pas de valeurs de paramètre de composant. Quand le composant ParameterParent
fournit des valeurs de paramètre de composant, celles-ci remplacent les valeurs par défaut du composant ParameterChild
.
Remarque
Pour plus de clarté, les classes de style CSS rendues ne sont pas affichées dans le balisage HTML rendu suivant.
<h1>Child component (without attribute values)</h1>
<div>
<div>Set By Child</div>
<div>Set by child.</div>
</div>
<h1>Child component (with attribute values)</h1>
<div>
<div>Set by Parent</div>
<div>Set by parent.</div>
</div>
Affectez un champ C#, une propriété ou le résultat d’une méthode à un paramètre de composant en tant que valeur d’attribut HTML. La valeur de l’attribut peut généralement être n’importe quelle expression C# qui correspond au type du paramètre. La valeur de l’attribut peut éventuellement mener avec un Razor symbole réservé@
, mais elle n’est pas obligatoire.
Si le paramètre de composant est de type chaîne, la valeur de l’attribut est traitée comme un littéral de chaîne C#. Si vous souhaitez spécifier une expression C# à la place, utilisez le préfixe @
.
Le composant ParameterParent2
suivant affiche quatre instances du composant ParameterChild
précédent et définit leurs valeurs de paramètre Title
avec :
- La valeur du champ
title
. - Le résultat de la méthode C#
GetTitle
. - La date locale actuelle au format long avec ToLongDateString, qui utilise une expression C# implicite.
- La propriété
Title
de l’objetpanelData
.
Les guillemets autour des valeurs d’attribut de paramètre sont facultatifs dans la plupart des cas, conformément à la spécification HTML5. Par exemple, Value=this
est pris en charge à la place de Value="this"
. Toutefois, nous vous recommandons d’utiliser des guillemets, car ils sont plus faciles à retenir et sont largement adoptés par les technologies web.
Tout au long de la documentation, les exemples de code se caractérisent comme suit :
- Ils utilisent toujours des guillemets. Exemple :
Value="this"
. - N’utilisez pas le préfixe
@
avec des types non littéraux, sauf si nécessaire. Exemple :Count="ct"
, oùct
est une variable de type nombre.Count="@ct"
est une approche stylistique valide, mais la documentation et les exemples n’adoptent pas la convention. - Toujours éviter
@
pour les littéraux, en dehors des expressions Razor. Exemple :IsFixed="true"
. Cela comprend les mots clés (par exemple,this
) etnull
, mais vous pouvez choisir de les utiliser si vous le souhaitez. Par exemple,IsFixed="@true"
est rare mais pris en charge.
Parameter2.razor
:
@page "/parameter-2"
<PageTitle>Parameter 2</PageTitle>
<h1>Parameter Example 2</h1>
<ParameterChild Title="@title" />
<ParameterChild Title="@GetTitle()" />
<ParameterChild Title="@DateTime.Now.ToLongDateString()" />
<ParameterChild Title="@panelData.Title" />
@code {
private string title = "From Parent field";
private PanelData panelData = new();
private string GetTitle() => "From Parent method";
private class PanelData
{
public string Title { get; set; } = "From Parent object";
}
}
Parameter2.razor
:
@page "/parameter-2"
<PageTitle>Parameter 2</PageTitle>
<h1>Parameter Example 2</h1>
<ParameterChild Title="@title" />
<ParameterChild Title="@GetTitle()" />
<ParameterChild Title="@DateTime.Now.ToLongDateString()" />
<ParameterChild Title="@panelData.Title" />
@code {
private string title = "From Parent field";
private PanelData panelData = new();
private string GetTitle() => "From Parent method";
private class PanelData
{
public string Title { get; set; } = "From Parent object";
}
}
ParameterParent2.razor
:
@page "/parameter-parent-2"
<ParameterChild Title="@title" />
<ParameterChild Title="@GetTitle()" />
<ParameterChild Title="@DateTime.Now.ToLongDateString()" />
<ParameterChild Title="@panelData.Title" />
@code {
private string title = "From Parent field";
private PanelData panelData = new();
private string GetTitle()
{
return "From Parent method";
}
private class PanelData
{
public string Title { get; set; } = "From Parent object";
}
}
ParameterParent2.razor
:
@page "/parameter-parent-2"
<ParameterChild Title="@title" />
<ParameterChild Title="@GetTitle()" />
<ParameterChild Title="@DateTime.Now.ToLongDateString()" />
<ParameterChild Title="@panelData.Title" />
@code {
private string title = "From Parent field";
private PanelData panelData = new();
private string GetTitle()
{
return "From Parent method";
}
private class PanelData
{
public string Title { get; set; } = "From Parent object";
}
}
ParameterParent2.razor
:
@page "/parameter-parent-2"
<ParameterChild Title="@title" />
<ParameterChild Title="@GetTitle()" />
<ParameterChild Title="@DateTime.Now.ToLongDateString()" />
<ParameterChild Title="@panelData.Title" />
@code {
private string title = "From Parent field";
private PanelData panelData = new PanelData();
private string GetTitle()
{
return "From Parent method";
}
private class PanelData
{
public string Title { get; set; } = "From Parent object";
}
}
Remarque
Lorsque vous affectez un membre C# à un paramètre de composant, ne préfixez pas l’attribut HTML du paramètre avec @
.
Correct (Title
est un paramètre de chaîne, Count
est un paramètre de type nombre) :
<ParameterChild Title="@title" Count="ct" />
<ParameterChild Title="@title" Count="@ct" />
Incorrect :
<ParameterChild @Title="@title" @Count="ct" />
<ParameterChild @Title="@title" @Count="@ct" />
Contrairement aux pages Razor (.cshtml
), Blazor ne peut pas effectuer de travail asynchrone dans une expression Razor lors du rendu d’un composant. En effet, Blazor est conçu pour le rendu d’interfaces utilisateur interactives. Dans une interface utilisateur interactive, l’écran doit toujours afficher quelque chose. Il n’est donc pas judicieux de bloquer le flux de rendu. Au lieu de cela, le travail asynchrone est effectué pendant l’un des événements de cycle de vie asynchrones. Après chaque événement de cycle de vie asynchrone, le composant peut être à nouveau rendu. La syntaxe Razor suivante n’est pas prise en charge :
<ParameterChild Title="await ..." />
<ParameterChild Title="@await ..." />
Le code de l’exemple précédent génère une erreur de compilateur quand l’application est générée :
L’opérateur « await » ne peut être utilisé que dans une méthode asynchrone. Envisagez de marquer cette méthode avec le modificateur « async » et de changer son type de retour en « Task ».
Pour obtenir une valeur pour le paramètre Title
dans l’exemple précédent de manière asynchrone, le composant peut utiliser l’événement de cycle de vie OnInitializedAsync
, comme le montre l’exemple suivant :
<ParameterChild Title="@title" />
@code {
private string? title;
protected override async Task OnInitializedAsync()
{
title = await ...;
}
}
Pour plus d’informations, consultez le cycle de vie des composants Razor ASP.NET Core.
L’utilisation d’une expression Razor explicite pour concaténer du texte avec un résultat d’expression pour affectation à un paramètre n’est pas prise en charge. L’exemple suivant cherche à concaténer le texte « Set by
» avec la valeur de propriété d’un objet. Bien que cette syntaxe soit prise en charge dans une page Razor (.cshtml
), elle n’est pas valide pour une affectation au paramètre Title
de l’enfant dans un composant. La syntaxe Razor suivante n’est pas prise en charge :
<ParameterChild Title="Set by @(panelData.Title)" />
Le code de l’exemple précédent génère une erreur de compilateur quand l’application est générée :
Les attributs de composant ne prennent pas en charge le contenu complexe (mélange C# et balisage).
Pour prendre en charge l’affectation d’une valeur composée, utilisez une méthode, un champ ou une propriété. L’exemple suivant concatène « Set by
» et la valeur de propriété d’un objet dans la méthode C# GetTitle
:
Parameter3.razor
:
@page "/parameter-3"
<PageTitle>Parameter 3</PageTitle>
<h1>Parameter Example 3</h1>
<ParameterChild Title="@GetTitle()" />
@code {
private PanelData panelData = new();
private string GetTitle() => $"Set by {panelData.Title}";
private class PanelData
{
public string Title { get; set; } = "Parent";
}
}
Parameter3.razor
:
@page "/parameter-3"
<PageTitle>Parameter 3</PageTitle>
<h1>Parameter Example 3</h1>
<ParameterChild Title="@GetTitle()" />
@code {
private PanelData panelData = new();
private string GetTitle() => $"Set by {panelData.Title}";
private class PanelData
{
public string Title { get; set; } = "Parent";
}
}
ParameterParent3.razor
:
@page "/parameter-parent-3"
<ParameterChild Title="@GetTitle()" />
@code {
private PanelData panelData = new();
private string GetTitle() => $"Set by {panelData.Title}";
private class PanelData
{
public string Title { get; set; } = "Parent";
}
}
ParameterParent3.razor
:
@page "/parameter-parent-3"
<ParameterChild Title="@GetTitle()" />
@code {
private PanelData panelData = new();
private string GetTitle() => $"Set by {panelData.Title}";
private class PanelData
{
public string Title { get; set; } = "Parent";
}
}
ParameterParent3.razor
:
@page "/parameter-parent-3"
<ParameterChild Title="@GetTitle()" />
@code {
private PanelData panelData = new();
private string GetTitle() => $"Set by {panelData.Title}";
private class PanelData
{
public string Title { get; set; } = "Parent";
}
}
ParameterParent3.razor
:
@page "/parameter-parent-3"
<ParameterChild Title="@GetTitle()" />
@code {
private PanelData panelData = new PanelData();
private string GetTitle() => $"Set by {panelData.Title}";
private class PanelData
{
public string Title { get; set; } = "Parent";
}
}
Pour en savoir plus, consultez les informations de référence sur la syntaxe Razor pour ASP.NET Core.
Warning
La spécification de valeurs initiales pour les paramètres de composant est prise en charge, mais ne créez pas de composant qui écrit dans ses propres paramètres après le rendu initial du composant. Pour plus d’informations, consultez Éviter le remplacement de paramètres dans ASP.NET Core Blazor.
Les paramètres de composant doivent être déclarés en tant que propriétés automatiques, ce qui signifie qu’ils ne doivent pas contenir de logique personnalisée dans leurs accesseurs get
ou set
. Par exemple, la propriété StartData
suivante est une propriété automatique :
[Parameter]
public DateTime StartData { get; set; }
Ne placez pas de logique personnalisée dans l’accesseur get
ou set
, car les paramètres de composant servent uniquement de canaux à l’aide desquels un composant parent peut transmettre des informations à un composant enfant. Si un accesseur set
d’une propriété de composant enfant contient une logique entraînant un nouveau rendu du composant parent, il en résulte une boucle de rendu infinie.
Pour transformer une valeur de paramètre reçue :
- Laissez la propriété de paramètre comme propriété automatique pour représenter les données brutes fournies.
- Créez une autre propriété ou méthode pour fournir les données transformées en fonction de la propriété de paramètre.
Remplacez OnParametersSetAsync
pour transformer un paramètre reçu chaque fois que de nouvelles données sont reçues.
L’écriture d’une valeur initiale dans un paramètre de composant est prise en charge, car les affectations de valeurs initiales n’interfèrent pas avec le rendu de composant automatique de Blazor. L’affectation suivante du DateTime local actuel avec DateTime.Now à StartData
est une syntaxe valide dans un composant :
[Parameter]
public DateTime StartData { get; set; } = DateTime.Now;
Après l’affectation initiale de DateTime.Now, n’attribuez pas de valeur à StartData
dans le code du développeur. Pour plus d’informations, consultez Éviter le remplacement de paramètres dans ASP.NET Core Blazor.
Appliquez l’attribut [EditorRequired]
pour spécifier un paramètre de composant obligatoire. Si une valeur de paramètre n’est pas fournie, les éditeurs ou les outils de génération peuvent présenter des avertissements à l’utilisateur. Cet attribut n’est valide que sur les propriétés également marquées avec l’attribut [Parameter]
. EditorRequiredAttribute est appliqué au moment de la conception et quand application est générée. L’attribut n’est pas appliqué au moment de l’exécution et ne garantit pas une valeur de paramètre différente de null
.
[Parameter]
[EditorRequired]
public string? Title { get; set; }
Les listes d’attributs monolignes sont également prises en charge :
[Parameter, EditorRequired]
public string? Title { get; set; }
N’utilisez pas le modificateurrequired
ou l’accesseurinit
propriétés des paramètres du composant. Les composants sont généralement instanciés et attribués aux valeurs de paramètre à l’aide de la réflexion, ce qui contourne les garanties qui init
et required
sont conçus pour effectuer. À la place, appliquez l’attribut[EditorRequired]
pour spécifier un paramètre de composant obligatoire.
N’utilisez pas l’accesseurinit
sur les propriétés des paramètres de composant, car la définition des valeurs de paramètre de composant avec ParameterView.SetParameterProperties utilise la réflexion, qui contourne la restriction setter init uniquement. Appliquez l’attribut [EditorRequired]
pour spécifier un paramètre de composant obligatoire.
N’utilisez pas l’accesseurinit
sur les propriétés des paramètres de composant, car la définition des valeurs de paramètre de composant avec ParameterView.SetParameterProperties utilise la réflexion, qui contourne la restriction setter init uniquement.
Les Tuples
(documentation de l’API) sont pris en charge pour les paramètres de composant et les types RenderFragment
. L’exemple de paramètre de composant suivant passe trois valeurs dans un Tuple
:
RenderTupleChild.razor
:
<div class="card w-50" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Tuple Card</div>
<div class="card-body">
<ul>
<li>Integer: @Data?.Item1</li>
<li>String: @Data?.Item2</li>
<li>Boolean: @Data?.Item3</li>
</ul>
</div>
</div>
@code {
[Parameter]
public (int, string, bool)? Data { get; set; }
}
RenderTupleParent.razor
:
@page "/render-tuple-parent"
<PageTitle>Render Tuple Parent</PageTitle>
<h1>Render Tuple Parent Example</h1>
<RenderTupleChild Data="data" />
@code {
private (int, string, bool) data = new(999, "I aim to misbehave.", true);
}
Les tuples nommés sont pris en charge, comme indiqué dans l’exemple suivant :
NamedTupleChild.razor
:
<div class="card w-50" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Tuple Card</div>
<div class="card-body">
<ul>
<li>Integer: @Data?.TheInteger</li>
<li>String: @Data?.TheString</li>
<li>Boolean: @Data?.TheBoolean</li>
</ul>
</div>
</div>
@code {
[Parameter]
public (int TheInteger, string TheString, bool TheBoolean)? Data { get; set; }
}
NamedTuples.razor
:
@page "/named-tuples"
<PageTitle>Named Tuples</PageTitle>
<h1>Named Tuples Example</h1>
<NamedTupleChild Data="data" />
@code {
private (int TheInteger, string TheString, bool TheBoolean) data =
new(999, "I aim to misbehave.", true);
}
Citation ©2005 Universal Pictures : Serenity (Nathan Fillion)
Les Tuples
(documentation de l’API) sont pris en charge pour les paramètres de composant et les types RenderFragment
. L’exemple de paramètre de composant suivant passe trois valeurs dans un Tuple
:
RenderTupleChild.razor
:
<div class="card w-50" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Tuple Card</div>
<div class="card-body">
<ul>
<li>Integer: @Data?.Item1</li>
<li>String: @Data?.Item2</li>
<li>Boolean: @Data?.Item3</li>
</ul>
</div>
</div>
@code {
[Parameter]
public (int, string, bool)? Data { get; set; }
}
RenderTupleParent.razor
:
@page "/render-tuple-parent"
<PageTitle>Render Tuple Parent</PageTitle>
<h1>Render Tuple Parent Example</h1>
<RenderTupleChild Data="data" />
@code {
private (int, string, bool) data = new(999, "I aim to misbehave.", true);
}
Les tuples nommés sont pris en charge, comme indiqué dans l’exemple suivant :
NamedTupleChild.razor
:
<div class="card w-50" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Tuple Card</div>
<div class="card-body">
<ul>
<li>Integer: @Data?.TheInteger</li>
<li>String: @Data?.TheString</li>
<li>Boolean: @Data?.TheBoolean</li>
</ul>
</div>
</div>
@code {
[Parameter]
public (int TheInteger, string TheString, bool TheBoolean)? Data { get; set; }
}
NamedTuples.razor
:
@page "/named-tuples"
<PageTitle>Named Tuples</PageTitle>
<h1>Named Tuples Example</h1>
<NamedTupleChild Data="data" />
@code {
private (int TheInteger, string TheString, bool TheBoolean) data =
new(999, "I aim to misbehave.", true);
}
Citation ©2005 Universal Pictures : Serenity (Nathan Fillion)
Les Tuples
(documentation de l’API) sont pris en charge pour les paramètres de composant et les types RenderFragment
. L’exemple de paramètre de composant suivant passe trois valeurs dans un Tuple
:
RenderTupleChild.razor
:
<div class="card w-50" style="margin-bottom:15px">
<div class="card-header font-weight-bold"><code>Tuple</code> Card</div>
<div class="card-body">
<ul>
<li>Integer: @Data?.Item1</li>
<li>String: @Data?.Item2</li>
<li>Boolean: @Data?.Item3</li>
</ul>
</div>
</div>
@code {
[Parameter]
public (int, string, bool)? Data { get; set; }
}
RenderTupleParent.razor
:
@page "/render-tuple-parent"
<h1>Render Tuple Parent</h1>
<RenderTupleChild Data="data" />
@code {
private (int, string, bool) data = new(999, "I aim to misbehave.", true);
}
Les tuples nommés sont pris en charge, comme indiqué dans l’exemple suivant :
RenderNamedTupleChild.razor
:
<div class="card w-50" style="margin-bottom:15px">
<div class="card-header font-weight-bold"><code>Tuple</code> Card</div>
<div class="card-body">
<ul>
<li>Integer: @Data?.TheInteger</li>
<li>String: @Data?.TheString</li>
<li>Boolean: @Data?.TheBoolean</li>
</ul>
</div>
</div>
@code {
[Parameter]
public (int TheInteger, string TheString, bool TheBoolean)? Data { get; set; }
}
RenderNamedTupleParent.razor
:
@page "/render-named-tuple-parent"
<h1>Render Named Tuple Parent</h1>
<RenderNamedTupleChild Data="data" />
@code {
private (int TheInteger, string TheString, bool TheBoolean) data =
new(999, "I aim to misbehave.", true);
}
Citation ©2005 Universal Pictures : Serenity (Nathan Fillion)
Paramètres de routage
Les composants peuvent spécifier des paramètres de routage dans le modèle de routage de la directive @page
. Le routeur Blazor utilise des paramètres de routage pour remplir les paramètres de composant correspondants.
RouteParameter1.razor
:
@page "/route-parameter-1/{text}"
<PageTitle>Route Parameter 1</PageTitle>
<h1>Route Parameter Example 1</h1>
<p>Blazor is @Text!</p>
@code {
[Parameter]
public string? Text { get; set; }
}
@page "/route-parameter-1/{text}"
<PageTitle>Route Parameter 1</PageTitle>
<h1>Route Parameter Example 1</h1>
<p>Blazor is @Text!</p>
@code {
[Parameter]
public string? Text { get; set; }
}
@page "/route-parameter-1/{text}"
<h1>Blazor is @Text!</h1>
@code {
[Parameter]
public string? Text { get; set; }
}
@page "/route-parameter-1/{text}"
<h1>Blazor is @Text!</h1>
@code {
[Parameter]
public string? Text { get; set; }
}
@page "/route-parameter-1/{text}"
<h1>Blazor is @Text!</h1>
@code {
[Parameter]
public string Text { get; set; }
}
@page "/route-parameter-1/{text}"
<h1>Blazor is @Text!</h1>
@code {
[Parameter]
public string Text { get; set; }
}
Pour obtenir plus d’informations, consultez la section des Paramètres de routage du routage et de la navigation ASP.NET Core Blazor. Les paramètres de routage facultatifs sont également pris en charge et abordés dans la même section. Pour obtenir plus d’informations sur les paramètres de routage catch-all ({*pageRoute}
), qui capturent les chemins dans les nombreuses limites du dossier, consultez la section Paramètres de routage catch-all du routage et de la navigation ASP.NET Core Blazor.
Pour obtenir plus d’informations, consultez la section des Paramètres de routage du routage et de la navigation ASP.NET Core Blazor. Les paramètres de routage facultatifs ne sont pas pris en charge. Par conséquent, deux directives @page
sont requises (consultez la section Paramètres de routage pour obtenir plus d’informations). Pour obtenir plus d’informations sur les paramètres de routage catch-all ({*pageRoute}
), qui capturent les chemins dans les nombreuses limites du dossier, consultez la section Paramètres de routage catch-all du routage et de la navigation ASP.NET Core Blazor.
Avertissement
Avec la compression, qui est activée par défaut, évitez de créer des composants côté serveur interactifs (authentifiés/autorisés) sécurisés qui affichent des données en provenance de sources non approuvées. Les sources non approuvées incluent les paramètres de routage, les chaînes de requête, les données de JS l’interopérabilité, et toute autre source de données qu’un utilisateur tiers peut contrôler (bases de données, services externes). Pour plus d’informations, consultez Conseils pour ASP.NET Core BlazorSignalR et Conseils d’atténuation des menaces pour le rendu interactif côté serveur de ASP.NET Core Blazor.
Fragments de rendu de contenu enfant
Les composants peuvent définir le contenu d’un autre composant. Le composant d’affectation fournit le contenu entre les balises d’ouverture et de fermeture du composant enfant.
Dans l’exemple suivant, le composant RenderFragmentChild
a un paramètre de composant ChildContent
qui représente un segment de l’interface utilisateur rendu en tant que RenderFragment. La position de ChildContent
dans le balisage Razor du composant correspond à l’emplacement où le contenu est rendu dans la sortie HTML finale.
RenderFragmentChild.razor
:
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Child content</div>
<div class="card-body">@ChildContent</div>
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Child content</div>
<div class="card-body">@ChildContent</div>
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Child content</div>
<div class="card-body">@ChildContent</div>
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Child content</div>
<div class="card-body">@ChildContent</div>
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Child content</div>
<div class="card-body">@ChildContent</div>
</div>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Child content</div>
<div class="card-body">@ChildContent</div>
</div>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}
Important
La propriété qui reçoit le contenu RenderFragment doit être nommée ChildContent
par convention.
Les rappels d’événements ne sont pas pris en charge pour RenderFragment.
Le composant suivant fournit du contenu pour générer le rendu de RenderFragmentChild
. Pour cela, le contenu est placé à l’intérieur des balises d’ouverture et de fermeture du composant enfant.
RenderFragments.razor
:
@page "/render-fragments"
<PageTitle>Render Fragments</PageTitle>
<h1>Render Fragments Example</h1>
<RenderFragmentChild>
Content of the child component is supplied
by the parent component.
</RenderFragmentChild>
RenderFragments.razor
:
@page "/render-fragments"
<PageTitle>Render Fragments</PageTitle>
<h1>Render Fragments Example</h1>
<RenderFragmentChild>
Content of the child component is supplied
by the parent component.
</RenderFragmentChild>
RenderFragmentParent.razor
:
@page "/render-fragment-parent"
<h1>Render child content</h1>
<RenderFragmentChild>
Content of the child component is supplied
by the parent component.
</RenderFragmentChild>
RenderFragmentParent.razor
:
@page "/render-fragment-parent"
<h1>Render child content</h1>
<RenderFragmentChild>
Content of the child component is supplied
by the parent component.
</RenderFragmentChild>
RenderFragmentParent.razor
:
@page "/render-fragment-parent"
<h1>Render child content</h1>
<RenderFragmentChild>
Content of the child component is supplied
by the parent component.
</RenderFragmentChild>
RenderFragmentParent.razor
:
@page "/render-fragment-parent"
<h1>Render child content</h1>
<RenderFragmentChild>
Content of the child component is supplied
by the parent component.
</RenderFragmentChild>
Des fragments de rendu sont utilisés pour générer le rendu du contenu enfant dans les applications Blazor et sont décrits avec des exemples dans les articles et sections d’article suivants :
- DispositionsBlazor
- Passer des données dans une hiérarchie de composants
- Composants basés sur un modèle
- Gestion globale des exceptions
Remarque
Les composants Razor intégrés du framework Blazor utilisent la même convention de paramètre de composant ChildContent
pour définir leur contenu. Vous pouvez voir les composants qui définissent le contenu enfant en recherchant le nom de propriété de paramètre de composant ChildContent
dans la documentation de l’API (filtre l’API avec le terme de recherche « ChildContent »).
Fragments de rendu pour une logique de rendu réutilisable
Vous pouvez employer des composants enfants dans le seul but de réutiliser la logique de rendu. Dans le bloc @code
d’un composant quelconque, définissez un RenderFragment et générez le rendu du fragment à partir de n’importe quel emplacement autant de fois que nécessaire :
@RenderWelcomeInfo
<p>Render the welcome info a second time:</p>
@RenderWelcomeInfo
@code {
private RenderFragment RenderWelcomeInfo = @<p>Welcome to your new app!</p>;
}
Pour plus d’informations, consultez Réutiliser la logique de rendu.
Variables de boucle avec des paramètres de composant et du contenu enfant
Le rendu de composants à l’intérieur d’une boucle for
nécessite une variable d’index local si la variable de boucle d’incrémentation est utilisée par les paramètres de composant ou le contenu enfant RenderFragment.
Considérez le composant suivant RenderFragmentChild2
qui a à la fois un paramètre de composant (Id
) et un fragment de rendu pour afficher le contenu enfant (ChildContent
).
RenderFragmentChild2.razor
:
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Child content (@Id)</div>
<div class="card-body">@ChildContent</div>
</div>
@code {
[Parameter]
public string? Id { get; set; }
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
Lors du rendu du composant RenderFragmentChild2
dans un composant parent, utilisez une variable d’index local (ct
dans l’exemple suivant) au lieu de la variable de boucle (c
) lors de l’attribution de la valeur du paramètre du composant et de la fourniture du contenu du composant enfant :
@for (int c = 1; c < 4; c++)
{
var ct = c;
<RenderFragmentChild2 Id="@($"Child{ct}")">
Count: @ct
</RenderFragmentChild2>
}
Vous pouvez également utiliser une boucle foreach
avec Enumerable.Range à la place d’une boucle for
.
@foreach (var c in Enumerable.Range(1, 3))
{
<RenderFragmentChild2 Id="@($"Child{c}")">
Count: @c
</RenderFragmentChild2>
}
Capturer les références à des composants
Les références de composants permettent de référencer une instance de composant pour émettre des commandes. Pour capturer une référence de composant :
- Ajoutez un attribut
@ref
au composant enfant. - Définissez un champ du même type que le composant enfant.
Quand le composant est rendu, le champ est rempli avec l’instance du composant. Vous pouvez ensuite appeler des méthodes .NET sur l’instance.
Considérez le composant ReferenceChild
suivant qui journalise un message quand son ChildMethod
est appelé.
ReferenceChild.razor
:
@inject ILogger<ReferenceChild> Logger
@if (value > 0)
{
<p>
<code>value</code>: @value
</p>
}
@code {
private int value;
public void ChildMethod(int value)
{
Logger.LogInformation("Received {Value} in ChildMethod", value);
this.value = value;
StateHasChanged();
}
}
@inject ILogger<ReferenceChild> Logger
@if (value > 0)
{
<p>
<code>value</code>: @value
</p>
}
@code {
private int value;
public void ChildMethod(int value)
{
Logger.LogInformation("Received {Value} in ChildMethod", value);
this.value = value;
StateHasChanged();
}
}
@using Microsoft.Extensions.Logging
@inject ILogger<ReferenceChild> Logger
@code {
public void ChildMethod(int value)
{
Logger.LogInformation("Received {Value} in ChildMethod", value);
}
}
@using Microsoft.Extensions.Logging
@inject ILogger<ReferenceChild> Logger
@code {
public void ChildMethod(int value)
{
Logger.LogInformation("Received {Value} in ChildMethod", value);
}
}
@using Microsoft.Extensions.Logging
@inject ILogger<ReferenceChild> Logger
@code {
public void ChildMethod(int value)
{
Logger.LogInformation("Received {Value} in ChildMethod", value);
}
}
@using Microsoft.Extensions.Logging
@inject ILogger<ReferenceChild> Logger
@code {
public void ChildMethod(int value)
{
Logger.LogInformation("Received {Value} in ChildMethod", value);
}
}
Une référence de composant n’est remplie qu’après le rendu du composant et sa sortie inclut l’élément de ReferenceChild
. Tant que le composant n’est pas rendu, il n’y a rien à référencer. N’essayez pas d’appeler une méthode de composant référencée directement à un gestionnaire d’événements (comme @onclick="childComponent!.ChildMethod(5)"
), car la variable de référence peut ne pas être attribuée au moment où l’événement click est attribué.
Pour manipuler les références de composant une fois le rendu du composant terminé, utilisez les méthodes OnAfterRender
ou OnAfterRenderAsync
.
L’exemple suivant utilise le composant ReferenceChild
précédent.
ReferenceParent.razor
:
@page "/reference-parent"
<div>
<button @onclick="@(() => childComponent1!.ChildMethod(5))">
Call <code>ReferenceChild.ChildMethod</code> (first instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent1" />
</div>
<div>
<button @onclick="CallChildMethod">
Call <code>ReferenceChild.ChildMethod</code> (second instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent2" />
</div>
@code {
private ReferenceChild? childComponent1;
private ReferenceChild? childComponent2;
private void CallChildMethod() => childComponent2!.ChildMethod(5);
}
@page "/reference-parent"
<div>
<button @onclick="@(() => childComponent1!.ChildMethod(5))">
Call <code>ReferenceChild.ChildMethod</code> (first instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent1" />
</div>
<div>
<button @onclick="CallChildMethod">
Call <code>ReferenceChild.ChildMethod</code> (second instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent2" />
</div>
@code {
private ReferenceChild? childComponent1;
private ReferenceChild? childComponent2;
private void CallChildMethod() => childComponent2!.ChildMethod(5);
}
@page "/reference-parent"
<div>
<button @onclick="@(() => childComponent1!.ChildMethod(5))">
Call <code>ReferenceChild.ChildMethod</code> (first instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent1" />
</div>
<div>
<button @onclick="CallChildMethod">
Call <code>ReferenceChild.ChildMethod</code> (second instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent2" />
</div>
@code {
private ReferenceChild? childComponent1;
private ReferenceChild? childComponent2;
private void CallChildMethod()
{
childComponent2!.ChildMethod(5);
}
}
@page "/reference-parent"
<div>
<button @onclick="@(() => childComponent1!.ChildMethod(5))">
Call <code>ReferenceChild.ChildMethod</code> (first instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent1" />
</div>
<div>
<button @onclick="CallChildMethod">
Call <code>ReferenceChild.ChildMethod</code> (second instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent2" />
</div>
@code {
private ReferenceChild? childComponent1;
private ReferenceChild? childComponent2;
private void CallChildMethod()
{
childComponent2!.ChildMethod(5);
}
}
@page "/reference-parent"
<div>
<button @onclick="@(() => childComponent1!.ChildMethod(5))">
Call <code>ReferenceChild.ChildMethod</code> (first instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent1" />
</div>
<div>
<button @onclick="CallChildMethod">
Call <code>ReferenceChild.ChildMethod</code> (second instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent2" />
</div>
@code {
private ReferenceChild childComponent1;
private ReferenceChild childComponent2;
private void CallChildMethod()
{
childComponent2!.ChildMethod(5);
}
}
@page "/reference-parent"
<div>
<button @onclick="@(() => childComponent1!.ChildMethod(5))">
Call <code>ReferenceChild.ChildMethod</code> (first instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent1" />
</div>
<div>
<button @onclick="CallChildMethod">
Call <code>ReferenceChild.ChildMethod</code> (second instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent2" />
</div>
@code {
private ReferenceChild childComponent1;
private ReferenceChild childComponent2;
private void CallChildMethod()
{
childComponent2!.ChildMethod(5);
}
}
Bien que la capture de références de composants utilise une syntaxe similaire à la capture de références d’éléments, il ne s’agit pas d’une fonctionnalité d’interopérabilité JavaScript. Les références de composants ne sont pas passées au code JavaScript. Les références de composants sont uniquement utilisées dans le code .NET.
Important
N’utilisez pas de références de composants pour muter l’état des composants enfants. Au lieu de cela, utilisez des paramètres de composant déclaratifs normaux pour passer des données aux composants enfants. L’utilisation de paramètres de composant entraîne la regénération automatique du rendu des composants enfants au bon moment. Pour plus d’informations, consultez la section sur les paramètres de composant et l’article sur la liaison de données Blazor ASP.NET Core.
Appliquer un attribut
Des attributs peuvent être appliqués à des composants avec la directive @attribute
. L’exemple suivant applique l’attribut [Authorize]
à la classe du composant :
@page "/"
@attribute [Authorize]
Attributs d’élément HTML conditionnels et propriétés DOM
Blazor adopte les comportements généraux suivants :
- Pour les attributs HTML, Blazor définit ou supprime l’attribut de manière conditionnelle en fonction de la valeur .NET. Si la valeur .NET est
false
ounull
, l’attribut n’est pas défini ou est supprimé s’il était précédemment défini. - Pour les propriétés DOM, comme
checked
ouvalue
, Blazor définit la propriété DOM en fonction de la valeur .NET. Si la valeur .NET estfalse
ounull
, la propriété DOM est réinitialisée sur une valeur par défaut.
Les attributs de syntaxe Razor qui correspondent aux attributs HTML et ceux qui correspondent aux propriétés DOM restent non documentés, car c’est un détail d’implémentation susceptible de changer sans préavis.
Avertissement
Certains attributs HTML, comme aria-pressed
, doivent avoir une valeur de chaîne « true » ou « false ». Comme ils nécessitent une valeur de chaîne et non une valeur booléenne, vous devez utiliser une valeur string
.NET et non une valeur bool
. Ces exigences sont définies par les API DOM du navigateur.
HTML brut
Les chaînes sont normalement rendues à l’aide de nœuds de texte DOM, ce qui signifie que le balisage qu’elles peuvent contenir est ignoré et traité comme du texte littéral. Pour générer le rendu de code HTML brut, wrappez le contenu HTML dans une valeur MarkupString. La valeur est analysée au format HTML ou SVG et insérée dans le DOM.
Warning
Le rendu de code HTML brut construit à partir d’une source non approuvée présente un risque de sécurité et doit toujours être évité.
L’exemple suivant montre comment utiliser le type MarkupString pour ajouter un bloc de contenu HTML statique à la sortie rendue d’un composant.
MarkupStrings.razor
:
@page "/markup-strings"
<PageTitle>Markup Strings</PageTitle>
<h1>Markup Strings Example</h1>
@((MarkupString)myMarkup)
@code {
private string myMarkup =
"<p class=\"text-danger\">This is a dangerous <em>markup string</em>.</p>";
}
MarkupStrings.razor
:
@page "/markup-strings"
<PageTitle>Markup Strings</PageTitle>
<h1>Markup Strings Example</h1>
@((MarkupString)myMarkup)
@code {
private string myMarkup =
"<p class=\"text-danger\">This is a dangerous <em>markup string</em>.</p>";
}
MarkupStringExample.razor
:
@page "/markup-string-example"
@((MarkupString)myMarkup)
@code {
private string myMarkup =
"<p class=\"text-danger\">This is a dangerous <em>markup string</em>.</p>";
}
MarkupStringExample.razor
:
@page "/markup-string-example"
@((MarkupString)myMarkup)
@code {
private string myMarkup =
"<p class=\"text-danger\">This is a dangerous <em>markup string</em>.</p>";
}
MarkupStringExample.razor
:
@page "/markup-string-example"
@((MarkupString)myMarkup)
@code {
private string myMarkup =
"<p class=\"text-danger\">This is a dangerous <em>markup string</em>.</p>";
}
MarkupStringExample.razor
:
@page "/markup-string-example"
@((MarkupString)myMarkup)
@code {
private string myMarkup =
"<p class=\"text-danger\">This is a dangerous <em>markup string</em>.</p>";
}
Modèles Razor
Les fragments de rendu peuvent être définis avec la syntaxe de modèle Razor pour définir un extrait de code d’interface utilisateur. Les modèles Razor utilisent le format suivant :
@<{HTML tag}>...</{HTML tag}>
L’exemple suivant montre comment spécifier les valeurs RenderFragment et RenderFragment<TValue> et générer le rendu de modèles directement dans un composant. Les fragments de rendu peuvent également être passés en tant qu’arguments aux composants basés sur un modèle.
RazorTemplate.razor
:
@page "/razor-template"
<PageTitle>Razor Template</PageTitle>
<h1>Razor Template Example</h1>
@timeTemplate
@petTemplate(new Pet { Name = "Nutty Rex" })
@code {
private RenderFragment timeTemplate = @<p>The time is @DateTime.Now.</p>;
private RenderFragment<Pet> petTemplate = (pet) => @<p>Pet: @pet.Name</p>;
private class Pet
{
public string? Name { get; set; }
}
}
@page "/razor-template"
<PageTitle>Razor Template</PageTitle>
<h1>Razor Template Example</h1>
@timeTemplate
@petTemplate(new Pet { Name = "Nutty Rex" })
@code {
private RenderFragment timeTemplate = @<p>The time is @DateTime.Now.</p>;
private RenderFragment<Pet> petTemplate = (pet) => @<p>Pet: @pet.Name</p>;
private class Pet
{
public string? Name { get; set; }
}
}
@page "/razor-template"
@timeTemplate
@petTemplate(new Pet { Name = "Nutty Rex" })
@code {
private RenderFragment timeTemplate = @<p>The time is @DateTime.Now.</p>;
private RenderFragment<Pet> petTemplate = (pet) => @<p>Pet: @pet.Name</p>;
private class Pet
{
public string? Name { get; set; }
}
}
@page "/razor-template"
@timeTemplate
@petTemplate(new Pet { Name = "Nutty Rex" })
@code {
private RenderFragment timeTemplate = @<p>The time is @DateTime.Now.</p>;
private RenderFragment<Pet> petTemplate = (pet) => @<p>Pet: @pet.Name</p>;
private class Pet
{
public string? Name { get; set; }
}
}
@page "/razor-template"
@timeTemplate
@petTemplate(new Pet { Name = "Nutty Rex" })
@code {
private RenderFragment timeTemplate = @<p>The time is @DateTime.Now.</p>;
private RenderFragment<Pet> petTemplate = (pet) => @<p>Pet: @pet.Name</p>;
private class Pet
{
public string Name { get; set; }
}
}
@page "/razor-template"
@timeTemplate
@petTemplate(new Pet { Name = "Nutty Rex" })
@code {
private RenderFragment timeTemplate = @<p>The time is @DateTime.Now.</p>;
private RenderFragment<Pet> petTemplate = (pet) => @<p>Pet: @pet.Name</p>;
private class Pet
{
public string Name { get; set; }
}
}
Sortie rendue du code précédent :
<p>The time is 4/19/2021 8:54:46 AM.</p>
<p>Pet: Nutty Rex</p>
Les ressources statiques
Blazor suit la convention des applications ASP.NET Core pour les ressources statiques. Les ressources statiques se trouvent dans le dossier web root
(wwwroot
) du projet ou dans des dossiers sous le dossier wwwroot
.
Utilisez un chemin relatif de base (/
) pour faire référence à la racine web d’une ressource statique. Dans l’exemple suivant, logo.png
se trouve physiquement dans le dossier {PROJECT ROOT}/wwwroot/images
. {PROJECT ROOT}
est la racine du projet de l’application.
<img alt="Company logo" src="/images/logo.png" />
Les composants ne prennent pas en charge la notation tilde-barre oblique (~/
).
Pour plus d’informations sur la définition du chemin de base d’une application, consultez Héberger et déployer Blazor ASP.NET Core.
Tag Helpers non pris en charge dans les composants
Les Tag Helpers
ne sont pas pris en charge dans les composants. Pour bénéficier d’une fonctionnalité de type Tag Helper dans Blazor, créez un composant avec la même fonctionnalité que le Tag Helper et utilisez le composant à la place.
Images SVG (Scalable Vector Graphics)
Étant donné que Blazor génère le rendu de code HTML, les images prises en charge par les navigateurs, notamment les images SVG (.svg
), sont prises en charge avec la balise <img>
:
<img alt="Example image" src="image.svg" />
De même, les images SVG sont prises en charge dans les règles CSS d’un fichier de feuille de style (.css
) :
.element-class {
background-image: url("image.svg");
}
Blazor prend en charge l’élément <foreignObject>
pour afficher du code HTML arbitraire dans un SVG. Le balisage peut représenter du code HTML arbitraire, un RenderFragment ou un composant Razor.
L’exemple suivant illustre cette situation :
- Affichage d’un
string
(@message
). - Liaison bidirectionnelle avec un élément
<input>
et un champvalue
. - Composant
Robot
.
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" rx="10" ry="10" width="200" height="200" stroke="black"
fill="none" />
<foreignObject x="20" y="20" width="160" height="160">
<p>@message</p>
</foreignObject>
</svg>
<svg xmlns="http://www.w3.org/2000/svg">
<foreignObject width="200" height="200">
<label>
Two-way binding:
<input @bind="value" @bind:event="oninput" />
</label>
</foreignObject>
</svg>
<svg xmlns="http://www.w3.org/2000/svg">
<foreignObject>
<Robot />
</foreignObject>
</svg>
@code {
private string message = "Lorem ipsum dolor sit amet, consectetur adipiscing " +
"elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
private string? value;
}
Comportement de rendu des espaces blancs
À moins que la directive @preservewhitespace
ne soit utilisée avec la valeur true
, un espace blanc supplémentaire est supprimé dans les cas suivants :
- Espace blanc de début ou de fin au sein d’un élément.
- Espace blanc de début ou de fin au sein d’un paramètre RenderFragment/RenderFragment<TValue> (par exemple, contenu enfant passé à un autre composant).
- Espace blanc précédant ou suivant un bloc de code C#, comme
@if
ou@foreach
.
La suppression de l’espace blanc peut affecter la sortie rendue lors de l’utilisation d’une règle CSS, par exemple white-space: pre
. Pour désactiver cette optimisation des performances et conserver l’espace blanc, effectuez l’une des actions suivantes :
- Ajoutez la directive
@preservewhitespace true
en haut du fichier Razor (.razor
) pour appliquer la préférence à un composant spécifique. - Ajoutez la directive
@preservewhitespace true
dans un fichier_Imports.razor
pour appliquer la préférence à un sous-répertoire ou à l’ensemble du projet.
Dans la plupart des cas, aucune action n’est requise car les applications continuent généralement à se comporter normalement (mais plus rapidement). Si la suppression d’un espace blanc entraîne un problème de rendu pour un composant particulier, utilisez @preservewhitespace true
dans ce composant pour désactiver cette optimisation.
L’espace blanc est conservé dans le balisage source d’un composant. Le texte d’espace blanc s’affiche uniquement dans le DOM du navigateur même si’n’y a aucun effet visuel.
Considérez le balisage du composant suivant :
<ul>
@foreach (var item in Items)
{
<li>
@item.Text
</li>
}
</ul>
L’exemple précédent génère le rendu de l’espace blanc inutile suivant :
- En dehors du bloc de code
@foreach
. - Autour de l’élément
<li>
. - Autour de la sortie
@item.Text
.
Une liste de 100 éléments donne lieu à plus de 400 zones d’espaces blancs. Aucun des espaces blancs supplémentaires n’affecte visuellement la sortie rendue.
Lors du rendu du code HTML statique pour les composants, les espaces blancs à l’intérieur d’une balise ne sont pas conservés. Par exemple, affichez la sortie rendue de la balise <img>
suivante dans un fichier Razor de composant (.razor
) :
<img alt="Example image" src="img.png" />
L’espace blanc n’est pas conservé du balisage précédent :
<img alt="Example image" src="img.png" />
Composant racine
Un composant Razor racine (composant racine) est le premier composant chargé d’une hiérarchie de composants créée par l’application.
Dans une application créée à partir du modèle de projet Blazor Web App, le composant App
(App.razor
) est spécifié comme composant racine par défaut par le paramètre de type déclaré pour l’appel à MapRazorComponents<TRootComponent>
dans le fichier Program
côté serveur. L’exemple suivant montre l’utilisation du composant App
comme composant racine, qui est la valeur par défaut d’une application créée à partir du modèle de projet Blazor :
app.MapRazorComponents<App>();
Remarque
La création d’un composant racine interactif, tel que le composant App
, n’est pas prise en charge.
Dans une application créée à partir du modèle de projet Blazor Server, le composant App
(App.razor
) est spécifié en tant que composant racine par défaut dans Pages/_Host.cshtml
à l’aide du Tag Helper de composant :
<component type="typeof(App)" render-mode="ServerPrerendered" />
Dans une application créée à partir du modèle de projet Blazor WebAssembly, le composant App
(App.razor
) est créé en tant que composant racine par défaut dans le fichierProgram
:
builder.RootComponents.Add<App>("#app");
Dans le code précédent, le sélecteur CSS, #app
, indique que le composant App
est spécifié pour le <div>
dans wwwroot/index.html
avec un id
de app
:
<div id="app">...</app>
Les applications MVC et Razor Pages peuvent également utiliser le Tag Helper de composant pour inscrire les composants racines rendus Blazor WebAssembly de manière statique :
<component type="typeof(App)" render-mode="WebAssemblyPrerendered" />
Les composants rendus de manière statique peuvent uniquement être ajoutés à l’application. Ils ne peuvent pas être supprimés ou mis à jour par la suite.
Pour plus d'informations, reportez-vous aux ressources suivantes :