Usar componentes do Razor em aplicativos JavaScript e estruturas SPA

Observação

Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Aviso

Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, confira .NET e a Política de Suporte do .NET Core. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Importante

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

Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Este artigo explica como renderizar componentes do Razor do JavaScript, usar elementos Blazor personalizados e gerar componentes Angular e React.

Observação

Recomendamos usar os scripts blazor.server.js (Blazor Server) e blazor.webassembly.js (Blazor WebAssembly) ao integrar os componentes Razor em um aplicativo JavaScript até que um melhor suporte para o script blazor.web.js (Blazor Web App) seja adicionado no futuro. Para obter mais informações, consulte RegisterCustomElement parou de funcionar no Blazor 8 (dotnet/aspnetcore #53920).

Aplicativos de exemplo angulares

Renderizar componentes Razor de JavaScript

Os componentes Razor podem ser renderizados dinamicamente do JavaScript (JS) para aplicativos JS existentes.

O exemplo nesta seção renderiza o componente do Razor a seguir em uma página por meio de JS.

Quote.razor:

<div class="m-5 p-5">
    <h2>Quote</h2>
    <p>@Text</p>
</div>

@code {
    [Parameter]
    public string? Text { get; set; }
}

No arquivo Program, adicione o namespace para o local do componente .

Chame RegisterForJavaScript na coleção de componentes raiz do aplicativo para registrar um componente Razor como um componente raiz para renderização de JS.

RegisterForJavaScript inclui uma sobrecarga que aceita o nome de uma função JS que executa a lógica de inicialização (javaScriptInitializer). A função JS é chamada uma vez por registro de componente imediatamente após o início do aplicativo Blazor e antes de todos os componentes serem renderizados. Essa função pode ser usada para integração com tecnologias JS, como elementos personalizados HTML ou uma estrutura SPA baseada em JS.

Uma ou mais funções de inicializador podem ser criadas e chamadas por diferentes registros de componente. O caso de uso típico é reutilizar a mesma função de inicializador para vários componentes, o que é esperado se a função de inicializador estiver configurando a integração com elementos personalizados ou outra estrutura SPA baseada em JS.

Importante

Não confunda o parâmetro javaScriptInitializer de RegisterForJavaScript com inicializadores JavaScript. O nome do parâmetro e o recurso de inicializadores de JS é coincidente.

O exemplo a seguir demonstra o registro dinâmico do componente anterior Quote com "quote" como o identificador.

  • Em um aplicativo Blazor Server, modifique a chamada para AddServerSideBlazor no arquivo Program:

    builder.Services.AddServerSideBlazor(options =>
    {
        options.RootComponents.RegisterForJavaScript<Quote>(identifier: "quote", 
            javaScriptInitializer: "initializeComponent");
    });
    
  • Em um aplicativo Blazor WebAssembly, chame RegisterForJavaScript em RootComponents no arquivo Program do lado do cliente:

    builder.RootComponents.RegisterForJavaScript<Quote>(identifier: "quote", 
        javaScriptInitializer: "initializeComponent");
    

Anexe a função inicializadora com name e os parâmetros de função e parameters ao objeto window. Para fins de demonstração, a função initializeComponent a seguir registra o nome e os parâmetros do componente registrado.

wwwroot/jsComponentInitializers.js:

window.initializeComponent = (name, parameters) => {
  console.log({ name: name, parameters: parameters });
}

Renderize o componente de JS em um elemento de contêiner usando o identificador registrado, passando parâmetros de componente conforme necessário.

No exemplo a seguir:

  • O componente Quote (identificador quote) é renderizado no elemento quoteContainer quando a função showQuote é chamada.
  • Uma cadeia de cota é passada para o parâmetro Text do componente.

wwwroot/scripts.js:

window.showQuote = async () => {
  let targetElement = document.getElementById('quoteContainer');
  await Blazor.rootComponents.add(targetElement, 'quote', 
  {
    text: "Crow: I have my doubts that this movie is actually 'starring' " +
      "anybody. More like, 'camera is generally pointed at.'"
  });
}

const btn = document.querySelector("showQuoteBtn");
btn.addEventListener("click", showQuote);

Depois que o script Blazor for carregado, carregue os scripts anteriores no aplicativo JS:

<script src="_framework/{BLAZOR SCRIPT}"></script>
<script src="jsComponentInitializers.js"></script>
<script src="scripts.js"></script>

No exemplo anterior, o espaço reservado {BLAZOR SCRIPT} é o script Blazor.

Em HTML, coloque o elemento de contêiner de destino (quoteContainer). Para a demonstração nesta seção, um botão dispara a renderização do componente Quote chamando a função showQuoteJS:

<button id="showQuoteBtn">Show Quote</button>

<div id="quoteContainer"></div>

Na inicialização, antes de qualquer componente ser renderizado, o console de ferramentas de desenvolvedor do navegador registra o identificador do componente Quote (name) e (parameters) quando initializeComponent é chamado:

Object { name: "quote", parameters: (1) […] }
  name: "quote"
  parameters: Array [ {…} ]
    0: Object { name: "Text", type: "string" }
    length: 1

Quando o botão Show Quote é selecionado, o componente Quote é renderizado com a cota armazenada em Text exibida:

Cota renderizada no navegador

Cota ©1988-1999 Satellite of Love LLC: Mystery Science Theater 3000 (Trace Beaulieu (Crow))

Observação

rootComponents.add Retorna uma instância do componente. Chame dispose na instância para liberá-la:

const rootComponent = await window.Blazor.rootComponents.add(...);

...

rootComponent.dispose();

O exemplo anterior renderiza dinamicamente o componente raiz quando a função showQuote()JS é chamada. Para renderizar um componente raiz em um elemento de contêiner quando Blazor for iniciado, use um inicializador JavaScript para renderizar o componente, como demonstra o exemplo a seguir.

O exemplo a seguir baseia-se no exemplo anterior, utilizando o componente Quote, o registro do componente raiz no arquivo Program e a inicialização de jsComponentInitializers.js. A função showQuote() (e o arquivo script.js) não é usada.

Em HTML, posicione o elemento de contêiner de destino, quoteContainer2 para este exemplo:

<div id="quoteContainer2"></div>

Usando um inicializador JavaScript, adicione o componente raiz ao elemento de contêiner de destino.

wwwroot/{PACKAGE ID/ASSEMBLY NAME}.lib.module.js:

export function afterStarted(blazor) {
  let targetElement = document.getElementById('quoteContainer2');
  blazor.rootComponents.add(targetElement, 'quote',
    {
      text: "Crow: I have my doubts that this movie is actually 'starring' " +
          "anybody. More like, 'camera is generally pointed at.'"
    });
}

Observação

Para a chamada para rootComponents.add, use o parâmetro blazor ( bem letras minúsculas) fornecido pelo evento de início Blazor. Embora o registro seja válido ao usar o objeto Blazor (B maiúsculo), a abordagem preferencial é usar o parâmetro.

Para obter um exemplo avançado com recursos adicionais, confira o exemplo no BasicTestApp da fonte de referência do ASP.NET Core (dotnet/aspnetcore repositório GitHub):

Observação

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

Elementos personalizados de Blazor

Use elementos personalizados de Blazor para renderizar dinamicamente componentes do Razor de outras estruturas SPA, como Angular ou React.

Elementos personalizados do Blazor:

  • Elementos personalizados usam interfaces HTML padrão para implementar elementos HTML personalizados.
  • Elimine a necessidade de gerenciar manualmente o estado e o ciclo de vida dos componentes raiz do Razor usando APIs JavaScript.
  • São úteis para introduzir gradualmente componentes do Razor em projetos existentes escritos em outras estruturas SPA.

Os elementos personalizados não dão suporte a conteúdo filho ou componentes em modelo.

Nome do elemento

De acordo com a especificação HTML, os nomes de marcas de elemento personalizados devem adotar estilo kebab:

Inválido: mycounter
Inválido: MY-COUNTER
Inválido: MyCounter
Válido: my-counter
Válido: my-cool-counter

Pacote

Adicione uma referência de pacote para Microsoft.AspNetCore.Components.CustomElements ao arquivo de projeto do aplicativo.

Observação

Para obter diretrizes sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes no Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas de pacote em NuGet.org.

Componente de exemplo

Os exemplos a seguir são baseados no componente Counter do modelo de projeto Blazor.

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++;
}

Registro de Blazor Server

Execute as etapas a seguir para registrar um componente raiz como um elemento personalizado em um aplicativo Blazor Server.

Adicione o namespace Microsoft.AspNetCore.Components.Web à parte superior do arquivo Program:

using Microsoft.AspNetCore.Components.Web;

Adicione um namespace para os componentes do aplicativo. No exemplo a seguir, o namespace do aplicativo é BlazorSample e os componentes estão localizados na pasta Pages:

using BlazorSample.Pages;

Modifique a chamada ao AddServerSideBlazor. Especifique o elemento personalizado com RegisterCustomElement na opção de circuito RootComponents. O exemplo a seguir registra o componente Counter com o elemento HTML my-counter personalizado :

builder.Services.AddServerSideBlazor(options =>
{
    options.RootComponents.RegisterCustomElement<Counter>("my-counter");
});

Registro de Blazor WebAssembly

Execute as etapas a seguir para registrar um componente raiz como um elemento personalizado em um aplicativo Blazor WebAssembly.

Adicione o namespace Microsoft.AspNetCore.Components.Web à parte superior do arquivo Program:

using Microsoft.AspNetCore.Components.Web;

Adicione um namespace para os componentes do aplicativo. No exemplo a seguir, o namespace do aplicativo é BlazorSample e os componentes estão localizados na pasta Pages:

using BlazorSample.Pages;

Chame RegisterCustomElement em RootComponents. O exemplo a seguir registra o componente Counter com o elemento HTML my-counter personalizado :

builder.RootComponents.RegisterCustomElement<Counter>("my-counter");

Usar o elemento personalizado registrado

Use o elemento personalizado com qualquer estrutura da Web. Por exemplo, o elemento HTML my-counter personalizado anterior que renderiza o componente Counter do aplicativo é usado em um aplicativo React com a seguinte marcação:

<my-counter></my-counter>

Para obter um exemplo completo de como criar elementos personalizados com Blazor, confira o componente CustomElementsComponent na origem de referência.

Observação

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

Parâmetros de passagem

Passe parâmetros para o componente Razor como atributos HTML ou como propriedades JavaScript no elemento DOM.

O componente a seguir Counter usa um IncrementAmount parâmetro para definir a quantidade de incremento do botão Click me.

Counter.razor:

@page "/counter"

<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;

    [Parameter]
    public int IncrementAmount { get; set; } = 1;

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

Renderize o componente Counter com o elemento personalizado e passe um valor para o parâmetro IncrementAmount como um atributo HTML. O nome do atributo adota a sintaxe de kebab (increment-amount, não IncrementAmount):

<my-counter increment-amount="10"></my-counter>

Como alternativa, você pode definir o valor do parâmetro como uma propriedade JavaScript no objeto de elemento. O nome do atributo adota a sintaxe camel (incrementAmount, não IncrementAmount):

const elem = document.querySelector("my-counter");
elem.incrementAmount = 10;

Você pode atualizar valores de parâmetro a qualquer momento usando a sintaxe de atributo ou propriedade.

Tipos de parâmetros com suporte:

  • Usando a sintaxe da propriedade JavaScript, você pode passar objetos de qualquer tipo serializável por JSON.
  • Usando atributos HTML, você fica limitado a passar objetos de tipos de cadeia de caracteres, boolianos ou numéricos.

O suporte experimental está disponível para a criação de elementos personalizados usando o pacote NuGet Microsoft.AspNetCore.Components.CustomElements. Elementos personalizados usam interfaces HTML padrão para implementar elementos HTML personalizados.

Aviso

Os recursos experimentais são fornecidos com a finalidade de explorar a viabilidade do recurso e podem não ser fornecidos em uma versão estável.

Registre um componente raiz como um elemento personalizado:

  • Em um aplicativo Blazor Server, modifique a chamada para AddServerSideBlazor no arquivo Program para chamar RegisterCustomElement em CircuitOptions.RootComponents:

    builder.Services.AddServerSideBlazor(options =>
    {
        options.RootComponents.RegisterCustomElement<Counter>("my-counter");
    });
    

    Observação

    O exemplo de código anterior requer um namespace para os componentes do aplicativo (por exemplo, using BlazorSample.Components.Pages;) no arquivo Program.

  • Em um aplicativo Blazor WebAssembly, chame RegisterCustomElement em WebAssemblyHostBuilder.RootComponents no arquivo Program:

    builder.RootComponents.RegisterCustomElement<Counter>("my-counter");
    

    Observação

    O exemplo de código anterior requer um namespace para os componentes do aplicativo (por exemplo, using BlazorSample.Components.Pages;) no arquivo Program.

Inclua a seguinte marca <script> no HTML do aplicativo antes da marca de script Blazor:

<script src="/_content/Microsoft.AspNetCore.Components.CustomElements/BlazorCustomElements.js"></script>

Use o elemento personalizado com qualquer estrutura da Web. Por exemplo, o elemento personalizado de contador anterior é usado em um aplicativo React com a seguinte marcação:

<my-counter increment-amount={incrementAmount}></my-counter>

Aviso

O recurso de elementos personalizados atualmente é experimental, sem suporte e está sujeito a alterações ou a ser removido a qualquer momento. Gostaríamos de receber comentários sobre como essa abordagem específica atende aos seus requisitos.

Gerar componentes Angular e React

Gere componentes JavaScript (JS) específicos da estrutura com base em componentes Razor para estruturas da Web, como Angular ou React. Essa funcionalidade não está incluída no .NET, mas é habilitada pelo suporte para renderizar de componentes Razor de JS. O exemplo de geração de componentes JS no GitHub demonstra como gerar componentes Angular e React de componentes Razor. Consulte o arquivo README.md do aplicativo de exemplo do GitHub para obter informações adicionais.

Aviso

Os recursos de componente Angular e React são experimentais, sem suporte e estão sujeitos a alterações ou a ser removidos a qualquer momento. Gostaríamos de receber comentários sobre como essa abordagem específica atende aos seus requisitos.