Crie componentes reutilizáveis da interface do usuário com Blazor
Gorjeta
Este conteúdo é um excerto do eBook, Blazor para ASP NET Web Forms Developers for Azure, disponível no .NET Docs ou como um PDF transferível gratuito que pode ser lido offline.
Uma das coisas bonitas sobre ASP.NET Web Forms é como ele permite o encapsulamento de partes reutilizáveis do código da interface do usuário (UI) em controles de interface do usuário reutilizáveis. Controles de usuário personalizados podem ser definidos na marcação usando arquivos .ascx . Você também pode criar controles de servidor elaborados em código com suporte total ao designer.
Blazor também suporta encapsulamento de interface do usuário por meio de componentes. Um componente:
- É um bloco autônomo da interface do usuário.
- Mantém seu próprio estado e lógica de renderização.
- Pode definir manipuladores de eventos da interface do usuário, vincular a dados de entrada e gerenciar seu próprio ciclo de vida.
- É normalmente definido em um arquivo .razor usando a sintaxe Razor.
Uma introdução ao Razor
Razor é uma linguagem de criação de modelos de marcação leve baseada em HTML e C#. Com o Razor, você pode fazer a transição perfeita entre marcação e código C# para definir sua lógica de renderização de componentes. Quando o arquivo .razor é compilado, a lógica de renderização é capturada de forma estruturada em uma classe .NET. O nome da classe compilada é retirado do nome do arquivo .razor . O namespace é retirado do namespace padrão para o projeto e o caminho da pasta, ou você pode especificar explicitamente o namespace usando a @namespace
diretiva (mais informações sobre diretivas Razor abaixo).
A lógica de renderização de um componente é criada usando marcação HTML normal com lógica dinâmica adicionada usando C#. O @
caractere é usado para fazer a transição para C#. O Razor normalmente é inteligente em descobrir quando você mudou de volta para HTML. Por exemplo, o componente a seguir renderiza uma <p>
tag com a hora atual:
<p>@DateTime.Now</p>
Para especificar explicitamente o início e o fim de uma expressão C#, use parênteses:
<p>@(DateTime.Now)</p>
O Razor também facilita o uso do fluxo de controle C# em sua lógica de renderização. Por exemplo, você pode condicionalmente renderizar algum HTML como este:
@if (value % 2 == 0)
{
<p>The value was even.</p>
}
Ou você pode gerar uma lista de itens usando um loop C# foreach
normal como este:
<ul>
@foreach (var item in items)
{
<li>@item.Text</li>
}
</ul>
As diretivas Razor, como as diretivas em ASP.NET Web Forms, controlam muitos aspetos de como um componente Razor é compilado. Exemplos incluem os componentes:
- Espaço de Nomes
- Classe base
- Interfaces implementadas
- Parâmetros genéricos
- Namespaces importados
- Rotas
As diretivas Razor começam com o @
caractere e normalmente são usadas no início de uma nova linha no início do arquivo. Por exemplo, a @namespace
diretiva define o namespace do componente:
@namespace MyComponentNamespace
A tabela a seguir resume as várias diretivas Razor usadas e Blazor seus equivalentes ASP.NET Web Forms, se existirem.
Diretiva | Description | Exemplo | Equivalente a Web Forms |
---|---|---|---|
@attribute |
Adiciona um atributo de nível de classe ao componente | @attribute [Authorize] |
Nenhuma |
@code |
Adiciona membros da classe ao componente | @code { ... } |
<script runat="server">...</script> |
@implements |
Implementa a interface especificada | @implements IDisposable |
Usar code-behind |
@inherits |
Herda da classe base especificada | @inherits MyComponentBase |
<%@ Control Inherits="MyUserControlBase" %> |
@inject |
Injeta um serviço no componente | @inject IJSRuntime JS |
Nenhuma |
@layout |
Especifica um componente de layout para o componente | @layout MainLayout |
<%@ Page MasterPageFile="~/Site.Master" %> |
@namespace |
Define o namespace para o componente | @namespace MyNamespace |
Nenhuma |
@page |
Especifica a rota para o componente | @page "/product/{id}" |
<%@ Page %> |
@typeparam |
Especifica um parâmetro de tipo genérico para o componente | @typeparam TItem |
Usar code-behind |
@using |
Especifica um namespace a ser incluído no escopo | @using MyComponentNamespace |
Adicionar namespace em web.config |
Os componentes do Razor também fazem uso extensivo de atributos de diretiva em elementos para controlar vários aspetos de como os componentes são compilados (manipulação de eventos, vinculação de dados, referências de elementos de componente e assim por diante). Todos os atributos da diretiva seguem uma sintaxe genérica comum, onde os valores entre parênteses são opcionais:
@directive(-suffix(:name))(="value")
A tabela a seguir resume os vários atributos para diretivas Razor usadas no Blazor.
Atributo | Description | Exemplo |
---|---|---|
@attributes |
Renderiza um dicionário de atributos | <input @attributes="ExtraAttributes" /> |
@bind |
Cria uma ligação de dados bidirecional | <input @bind="username" @bind:event="oninput" /> |
@on{event} |
Adiciona um manipulador de eventos para o evento especificado | <button @onclick="IncrementCount">Click me!</button> |
@key |
Especifica uma chave a ser usada pelo algoritmo de diferenciação para preservar elementos em uma coleção | <DetailsEditor @key="person" Details="person.Details" /> |
@ref |
Captura uma referência ao componente ou elemento HTML | <MyDialog @ref="myDialog" /> |
Os vários atributos da diretiva utilizados por Blazor (@onclick
, @bind
, @ref
, e assim por diante) são abordados nas secções abaixo e nos capítulos seguintes.
Muitas das sintaxes usadas nos arquivos .aspx e .ascx têm sintaxes paralelas no Razor. Abaixo está uma comparação simples das sintaxes para ASP.NET Web Forms e Razor.
Caraterística | Web Forms | Sintaxe | Navalha | Sintaxe |
---|---|---|---|---|
Diretivas | <%@ [directive] %> |
<%@ Page %> |
@[directive] |
@page |
Blocos de código | <% %> |
<% int x = 123; %> |
@{ } |
@{ int x = 123; } |
Expressões (codificado em HTML) |
<%: %> |
<%:DateTime.Now %> |
Implícito: @ Explícito: @() |
@DateTime.Now @(DateTime.Now) |
Comentários | <%-- --%> |
<%-- Commented --%> |
@* *@ |
@* Commented *@ |
Vinculação de dados | <%# %> |
<%# Bind("Name") %> |
@bind |
<input @bind="username" /> |
Para adicionar membros à classe de componente Razor, use a @code
diretiva . Essa técnica é semelhante ao uso de um <script runat="server">...</script>
bloco em uma página ou controle de usuário ASP.NET Web Forms.
@code {
int count = 0;
void IncrementCount()
{
count++;
}
}
Como o Razor é baseado em C#, ele deve ser compilado de dentro de um projeto C# (.csproj). Você não pode compilar arquivos .razor de um projeto Visual Basic (.vbproj). Você ainda pode fazer referência a projetos do Visual Basic do seu Blazor projeto. O contrário também é verdadeiro.
Para obter uma referência de sintaxe completa do Razor, consulte Referência de sintaxe do Razor para ASP.NET Core.
Usar componentes
Além do HTML normal, os componentes também podem usar outros componentes como parte de sua lógica de renderização. A sintaxe para usar um componente no Razor é semelhante ao uso de um controle de usuário em um aplicativo ASP.NET Web Forms. Os componentes são especificados usando uma marca de elemento que corresponde ao nome do tipo do componente. Por exemplo, você pode adicionar um Counter
componente como este:
<Counter />
Ao contrário ASP.NET Web Forms, os componentes em Blazor:
- Não use um prefixo de elemento (por exemplo,
asp:
). - Não requer registo na página ou no web.config.
Pense nos componentes do Razor como você faria com os tipos .NET, porque é exatamente isso que eles são. Se o conjunto que contém o componente for referenciado, o componente estará disponível para uso. Para trazer o namespace do componente para o escopo, aplique a @using
diretiva:
@using MyComponentLib
<Counter />
Como visto nos projetos padrão Blazor , é comum colocar @using
diretivas em um arquivo _Imports.razor para que elas sejam importadas para todos os arquivos .razor no mesmo diretório e em diretórios filho.
Se o namespace de um componente não estiver no escopo, você poderá especificar um componente usando seu nome de tipo completo, como em C#:
<MyComponentLib.Counter />
Modificar o título da página a partir dos componentes
Ao criar aplicativos no estilo SPA, é comum que partes de uma página sejam recarregadas sem recarregar a página inteira. Mesmo assim, pode ser útil ter o título da página alterado com base em qual componente está carregado no momento. Isso pode ser feito incluindo a <PageTitle>
tag na página Razor do componente:
@page "/"
<PageTitle>Home</PageTitle>
O conteúdo deste elemento pode ser dinâmico, por exemplo, mostrando a contagem atual de mensagens:
<PageTitle>@MessageCount messages</PageTitle>
Observe que, se vários componentes em uma determinada página incluírem <PageTitle>
tags, apenas a última será exibida (já que cada uma substituirá a anterior).
Parâmetros dos componentes
No ASP.NET Web Forms, você pode fluir parâmetros e dados para controles usando propriedades públicas. Essas propriedades podem ser definidas na marcação usando atributos ou definidas diretamente no código. Os componentes do Razor funcionam de maneira semelhante, embora as propriedades do componente também devam ser marcadas com o [Parameter]
atributo para serem considerados parâmetros do componente.
O componente a seguir Counter
define um parâmetro de componente chamado IncrementAmount
que pode ser usado para especificar a quantidade que o deve ser incrementado Counter
cada vez que o botão é clicado.
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
int currentCount = 0;
[Parameter]
public int IncrementAmount { get; set; } = 1;
void IncrementCount()
{
currentCount+=IncrementAmount;
}
}
Para especificar um parâmetro de componente no Blazor, use um atributo como faria em ASP.NET Web Forms:
<Counter IncrementAmount="10" />
Parâmetros da cadeia de caracteres de consulta
Os componentes do Razor também podem aproveitar valores da cadeia de caracteres de consulta da página em que são renderizados como uma fonte de parâmetro. Para habilitar isso, adicione o [SupplyParameterFromQuery]
atributo ao parâmetro. Por exemplo, a seguinte definição de parâmetro obteria seu valor da solicitação no formato ?IncBy=2
:
[Parameter]
[SupplyParameterFromQuery(Name = "IncBy")]
public int IncrementAmount { get; set; } = 1;
Se você não fornecer um personalizado Name
no [SupplyParameterFromQuery]
atributo, por padrão, ele corresponderá ao nome da propriedade (IncrementAmount
neste caso).
Componentes e limites de erro
Por padrão, os aplicativos detetam exceções não tratadas e mostram uma mensagem de erro na parte inferior da página, Blazor sem detalhes adicionais. Para restringir as partes do aplicativo que são afetadas por um erro não tratado, por exemplo, para limitar o impacto a um único componente, a <ErrorBoundary>
tag pode ser encapsulada em declarações de componente.
Por exemplo, para proteger contra possíveis exceções lançadas do componente, declare-o Counter
dentro de um <ErrorBoundary>
e, opcionalmente, especifique uma mensagem a ser exibida se houver uma exceção:
<ErrorBoundary>
<ChildContent>
<Counter />
</ChildContent>
<ErrorContent>
Oops! The counter isn't working right now; please try again later.
</ErrorContent>
</ErrorBoundary>
Se você não precisar especificar o conteúdo de erro personalizado, basta encapsular o componente diretamente:
<ErrorBoundary>
<Counter />
</ErrorBoundary>
Uma mensagem padrão informando "Um erro como ocorreu." será exibida se ocorrer uma exceção sem tratamento no componente encapsulado.
Processadores de eventos
Ambos ASP.NET Web Forms e Blazor fornecem um modelo de programação baseado em eventos para manipular eventos da interface do usuário. Exemplos de tais eventos incluem cliques em botões e entrada de texto. Em ASP.NET Web Forms, você usa controles de servidor HTML para manipular eventos de interface do usuário expostos pelo DOM ou pode manipular eventos expostos por controles de servidor Web. Os eventos são exibidos no servidor por meio de solicitações de post-back de formulário. Considere o seguinte exemplo de clique no botão Web Forms:
Conta.ascx
<asp:Button ID="ClickMeButton" runat="server" Text="Click me!" OnClick="ClickMeButton_Click" />
Counter.ascx.cs
public partial class Counter : System.Web.UI.UserControl
{
protected void ClickMeButton_Click(object sender, EventArgs e)
{
Console.WriteLine("The button was clicked!");
}
}
No Blazor, você pode registrar manipuladores para eventos da interface do usuário do DOM diretamente usando atributos de diretiva do formulário @on{event}
. O {event}
espaço reservado representa o nome do evento. Por exemplo, você pode ouvir cliques de botões como este:
<button @onclick="OnClick">Click me!</button>
@code {
void OnClick()
{
Console.WriteLine("The button was clicked!");
}
}
Os manipuladores de eventos podem aceitar um argumento opcional específico do evento para fornecer mais informações sobre o evento. Por exemplo, eventos do mouse podem ter um MouseEventArgs
argumento, mas não é necessário.
<button @onclick="OnClick">Click me!</button>
@code {
void OnClick(MouseEventArgs e)
{
Console.WriteLine($"Mouse clicked at {e.ScreenX}, {e.ScreenY}.");
}
}
Em vez de se referir a um grupo de métodos para um manipulador de eventos, você pode usar uma expressão lambda. Uma expressão lambda permite que você feche sobre outros valores no escopo.
@foreach (var buttonLabel in buttonLabels)
{
<button @onclick="() => Console.WriteLine($"The {buttonLabel} button was clicked!")">@buttonLabel</button>
}
Os manipuladores de eventos podem ser executados de forma síncrona ou assíncrona. Por exemplo, o seguinte OnClick
manipulador de eventos é executado de forma assíncrona:
<button @onclick="OnClick">Click me!</button>
@code {
async Task OnClick()
{
var result = await Http.GetAsync("api/values");
}
}
Depois que um evento é manipulado, o componente é renderizado para contabilizar quaisquer alterações de estado do componente. Com manipuladores de eventos assíncronos, o componente é renderizado imediatamente após a conclusão da execução do manipulador. O componente é renderizado novamente após a conclusão assíncrona Task
. Esse modo de execução assíncrona oferece uma oportunidade de renderizar alguma interface do usuário apropriada enquanto o assíncrono Task
ainda está em andamento.
<button @onclick="ShowMessage">Get message</button>
@if (showMessage)
{
@if (message == null)
{
<p><em>Loading...</em></p>
}
else
{
<p>The message is: @message</p>
}
}
@code
{
bool showMessage = false;
string message;
public async Task ShowMessage()
{
showMessage = true;
message = await MessageService.GetMessageAsync();
}
}
Os componentes também podem definir seus próprios eventos definindo um parâmetro de componente do tipo EventCallback<TValue>
. Os retornos de chamada de eventos suportam todas as variações dos manipuladores de eventos da interface do usuário do DOM: argumentos opcionais, síncronos ou assíncronos, grupos de métodos ou expressões lambda.
<button class="btn btn-primary" @onclick="OnClick">Click me!</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClick { get; set; }
}
Vinculação de dados
Blazor fornece um mecanismo simples para vincular dados de um componente da interface do usuário ao estado do componente. Essa abordagem difere dos recursos em ASP.NET Web Forms para vincular dados de fontes de dados a controles de interface do usuário. Abordaremos o tratamento de dados de diferentes fontes de dados na seção Lidando com dados .
Para criar uma ligação de dados bidirecional de um componente da interface do usuário para o estado do componente, use o @bind
atributo directive . No exemplo a seguir, o valor da caixa de seleção está vinculado ao isChecked
campo.
<input type="checkbox" @bind="isChecked" />
@code {
bool isChecked;
}
Quando o componente é renderizado, o valor da caixa de seleção é definido como o valor do isChecked
campo. Quando o usuário alterna a caixa de seleção, o evento é disparado onchange
e o isChecked
campo é definido como o novo valor. A @bind
sintaxe, neste caso, é equivalente à seguinte marcação:
<input value="@isChecked" @onchange="(UIChangeEventArgs e) => isChecked = e.Value" />
Para alterar o evento usado para a ligação, use o @bind:event
atributo.
<input @bind="text" @bind:event="oninput" />
<p>@text</p>
@code {
string text;
}
Os componentes também podem suportar a vinculação de dados aos seus parâmetros. Para vinculação de dados, defina um parâmetro de retorno de chamada de evento com o mesmo nome do parâmetro vinculável. O sufixo "Changed" é adicionado ao nome.
PasswordBox.razor
Password: <input
value="@Password"
@oninput="OnPasswordChanged"
type="@(showPassword ? "text" : "password")" />
<label><input type="checkbox" @bind="showPassword" />Show password</label>
@code {
private bool showPassword;
[Parameter]
public string Password { get; set; }
[Parameter]
public EventCallback<string> PasswordChanged { get; set; }
private Task OnPasswordChanged(ChangeEventArgs e)
{
Password = e.Value.ToString();
return PasswordChanged.InvokeAsync(Password);
}
}
Para encadear uma ligação de dados a um elemento de interface do usuário subjacente, defina o valor e manipule o evento diretamente no elemento da interface do usuário em vez de usar o @bind
atributo.
Para vincular a um parâmetro de componente, use um @bind-{Parameter}
atributo para especificar o parâmetro ao qual você deseja vincular.
<PasswordBox @bind-Password="password" />
@code {
string password;
}
Alterações de estado
Se o estado do componente tiver sido alterado fora de um evento normal da interface do usuário ou retorno de chamada de evento, o componente deverá sinalizar manualmente que precisa ser renderizado novamente. Para sinalizar que o estado de um componente foi alterado, chame o StateHasChanged
método no componente.
No exemplo abaixo, um componente exibe uma mensagem de um AppState
serviço que pode ser atualizada por outras partes do aplicativo. O componente registra seu StateHasChanged
método com o AppState.OnChange
evento para que o componente seja renderizado sempre que a mensagem for atualizada.
public class AppState
{
public string Message { get; }
// Lets components receive change notifications
public event Action OnChange;
public void UpdateMessage(string message)
{
Message = message;
NotifyStateChanged();
}
private void NotifyStateChanged() => OnChange?.Invoke();
}
@inject AppState AppState
<p>App message: @AppState.Message</p>
@code {
protected override void OnInitialized()
{
AppState.OnChange += StateHasChanged
}
}
Ciclo de vida dos componentes
A estrutura ASP.NET Web Forms tem métodos de ciclo de vida bem definidos para módulos, páginas e controles. Por exemplo, o controle a seguir implementa manipuladores de eventos para os Init
eventos , Load
e UnLoad
ciclo de vida:
Counter.ascx.cs
public partial class Counter : System.Web.UI.UserControl
{
protected void Page_Init(object sender, EventArgs e) { ... }
protected void Page_Load(object sender, EventArgs e) { ... }
protected void Page_UnLoad(object sender, EventArgs e) { ... }
}
Os componentes da navalha também têm um ciclo de vida bem definido. O ciclo de vida de um componente pode ser usado para inicializar o estado do componente e implementar comportamentos avançados do componente.
Todos os métodos de ciclo de vida dos componentes do Blazortêm versões síncronas e assíncronas. A renderização de componentes é síncrona. Não é possível executar lógica assíncrona como parte da renderização do componente. Toda a lógica assíncrona deve ser executada como parte de um async
método de ciclo de vida.
OnInitialized
Os OnInitialized
métodos e OnInitializedAsync
são usados para inicializar o componente. Um componente normalmente é inicializado depois de ser renderizado pela primeira vez. Depois que um componente é inicializado, ele pode ser renderizado várias vezes antes de ser eventualmente descartado. O OnInitialized
método é semelhante ao Page_Load
evento em ASP.NET páginas e controles de Web Forms.
protected override void OnInitialized() { ... }
protected override async Task OnInitializedAsync() { await ... }
OnParametersSet
Os OnParametersSet
métodos e OnParametersSetAsync
são chamados quando um componente recebeu parâmetros de seu pai e o valor é atribuído às propriedades. Esses métodos são executados após a inicialização do componente e cada vez que o componente é renderizado.
protected override void OnParametersSet() { ... }
protected override async Task OnParametersSetAsync() { await ... }
OnAfterRender
Os OnAfterRender
métodos e OnAfterRenderAsync
são chamados depois que um componente termina a renderização. As referências de elementos e componentes são preenchidas neste ponto (mais informações sobre esses conceitos abaixo). A interatividade com o navegador está ativada neste momento. As interações com a execução de DOM e JavaScript podem ocorrer com segurança.
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
...
}
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await ...
}
}
OnAfterRender
e OnAfterRenderAsync
não são chamados durante a pré-renderização no servidor.
O firstRender
parâmetro é true
a primeira vez que o componente é renderizado, caso contrário, seu valor é false
.
IDisposable
Os componentes do Razor podem ser implementados IDisposable
para descartar recursos quando o componente é removido da interface do usuário. Um componente Razor pode implementar IDispose
usando a @implements
diretiva:
@using System
@implements IDisposable
...
@code {
public void Dispose()
{
...
}
}
Capturar referências de componentes
Em ASP.NET Web Forms, é comum manipular uma instância de controle diretamente no código referindo-se à sua ID. No Blazor, também é possível capturar e manipular uma referência a um componente, embora seja muito menos comum.
Para capturar uma referência de componente no Blazor, use o @ref
atributo directive . O valor do atributo deve corresponder ao nome de um campo configurável com o mesmo tipo do componente referenciado.
<MyLoginDialog @ref="loginDialog" ... />
@code {
MyLoginDialog loginDialog = default!;
void OnSomething()
{
loginDialog.Show();
}
}
Quando o componente pai é renderizado, o campo é preenchido com a instância do componente filho. Em seguida, você pode chamar métodos ou manipular a instância do componente.
Não é recomendável manipular o estado do componente diretamente usando referências de componentes. Isso evita que o componente seja processado automaticamente nos momentos corretos.
Capturar referências de elementos
Os componentes do Razor podem capturar referências a um elemento. Ao contrário dos controles de servidor HTML em ASP.NET Web Forms, você não pode manipular o DOM diretamente usando uma referência de elemento no Blazor. Blazor lida com a maioria das interações DOM para você usando seu algoritmo de diferenciação DOM. As referências de elementos capturados são Blazor opacas. No entanto, eles são usados para passar uma referência de elemento específico em uma chamada de interoperabilidade JavaScript. Para obter mais informações sobre interoperabilidade JavaScript, consulte Interoperabilidade JavaScript ASP.NET CoreBlazor.
Componentes modelados:
No ASP.NET Web Forms, você pode criar controles de modelo. Os controles de modelo permitem que o desenvolvedor especifique uma parte do HTML usado para renderizar um controle de contêiner. A mecânica de criação de controles de servidor com modelos é complexa, mas permite cenários poderosos para renderizar dados de forma personalizável pelo usuário. Exemplos de controles de modelo incluem Repeater
e DataList
.
Os componentes do Razor também podem ser modelados definindo parâmetros de componentes do tipo RenderFragment
ou RenderFragment<T>
. A RenderFragment
representa um pedaço de marcação Razor que pode ser renderizado pelo componente. A RenderFragment<T>
é um pedaço da marcação Razor que usa um parâmetro que pode ser especificado quando o fragmento de renderização é renderizado.
Conteúdo infantil
Os componentes do Razor podem capturar seu conteúdo filho como um RenderFragment
e renderizar esse conteúdo como parte da renderização do componente. Para capturar conteúdo filho, defina um parâmetro de componente do tipo RenderFragment
e nomeie-o ChildContent
.
ChildContentComponent.razor
<h1>Component with child content</h1>
<div>@ChildContent</div>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}
Um componente pai pode então fornecer conteúdo filho usando a sintaxe normal do Razor.
<ChildContentComponent>
<ChildContent>
<p>The time is @DateTime.Now</p>
</ChildContent>
</ChildContentComponent>
Parâmetros do modelo
Um componente Razor modelado também pode definir vários parâmetros de componentes do tipo RenderFragment
ou RenderFragment<T>
. O parâmetro for a RenderFragment<T>
pode ser especificado quando é invocado. Para especificar um parâmetro de tipo genérico para um componente, use a @typeparam
diretiva Razor.
SimpleListView.razor
@typeparam TItem
@Heading
<ul>
@foreach (var item in Items)
{
<li>@ItemTemplate(item)</li>
}
</ul>
@code {
[Parameter]
public RenderFragment Heading { get; set; }
[Parameter]
public RenderFragment<TItem> ItemTemplate { get; set; }
[Parameter]
public IEnumerable<TItem> Items { get; set; }
}
Ao usar um componente de modelo, os parâmetros do modelo podem ser especificados usando elementos filho que correspondem aos nomes dos parâmetros. Os argumentos de componentes do tipo RenderFragment<T>
passados como elementos têm um parâmetro implícito chamado context
. Você pode alterar o nome desse parâmetro de implementação usando o Context
atributo no elemento filho. Qualquer parâmetro de tipo genérico pode ser especificado usando um atributo que corresponde ao nome do parâmetro type. O parâmetro type será inferido, se possível:
<SimpleListView Items="messages" TItem="string">
<Heading>
<h1>My list</h1>
</Heading>
<ItemTemplate Context="message">
<p>The message is: @message</p>
</ItemTemplate>
</SimpleListView>
A saída deste componente tem esta aparência:
<h1>My list</h1>
<ul>
<li><p>The message is: message1</p></li>
<li><p>The message is: message2</p></li>
<ul>
Code-behind
Um componente Razor é normalmente criado em um único arquivo .razor . No entanto, também é possível separar o código e a marcação usando um arquivo code-behind. Para usar um arquivo de componente, adicione um arquivo C# que corresponda ao nome do arquivo do componente, mas com uma extensão de .cs adicionada (Counter.razor.cs). Use o arquivo C# para definir uma classe base para o componente. Você pode nomear a classe base como quiser, mas é comum nomear a classe da mesma forma que a classe do componente, mas com uma Base
extensão adicionada (CounterBase
). A classe baseada em componente também deve derivar de ComponentBase
. Em seguida, no arquivo de componente Razor, adicione a @inherits
diretiva para especificar a classe base para o componente (@inherits CounterBase
).
Conta.razor
@inherits CounterBase
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button @onclick="IncrementCount">Click me</button>
Counter.razor.cs
public class CounterBase : ComponentBase
{
protected int currentCount = 0;
protected void IncrementCount()
{
currentCount++;
}
}
A visibilidade dos membros do componente na classe base deve ser protected
ou public
ser visível para a classe do componente.
Recursos adicionais
O precedente não é um tratamento exaustivo de todos os aspetos dos componentes do Razor. Para obter mais informações sobre como criar e usar ASP.NET componentes do Core Razor, consulte a Blazor documentação.