Uso de componentes Razor en aplicaciones de JavaScript y marcos SPA

Nota

Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión .NET 8 de este artículo.

Importante

Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.

Para la versión actual, consulte la versión .NET 8 de este artículo.

En este artículo se explica cómo representar los componentes Razor de JavaScript, cómo usar elementos Blazor personalizados y cómo generar componentes de Angular y React.

Aplicaciones de ejemplo de Angular

Representación de componentes Razor desde JavaScript

Los componentes Razor se pueden representar dinámicamente desde JavaScript (JS) para las aplicaciones de JS existentes.

El ejemplo de esta sección representa el componente Razor siguiente en una página a través de JS.

Quote.razor:

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

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

En el archivo Program, agregue el espacio de nombres para la ubicación del componente.

Llame a RegisterForJavaScript en la colección de componentes raíz de la aplicación para registrar el componente de Razor como componente raíz para la representación de JS.

RegisterForJavaScript incluye una sobrecarga que acepta el nombre de una función JS que ejecuta la lógica de inicialización (javaScriptInitializer). Se llama a la función JS una vez por cada registro de componente inmediatamente después de que se inicie la aplicación Blazor y antes de que se represente cualquier componente. Esta función se puede usar para la integración con las tecnologías JS, como elementos personalizados HTML o un marco SPA basado en JS.

Se pueden crear una o varias funciones de inicializador y llamarlas mediante registros de componentes distintos. El caso de uso típico consiste en reutilizar la misma función de inicializador para varios componentes, lo cual se espera si la función de inicializador configura la integración con elementos personalizados o con otro marco SPA basado en JS.

Importante

No confunda el parámetro javaScriptInitializer de RegisterForJavaScript con los inicializadores de JavaScript. La coincidencia del nombre del parámetro y la característica de inicializadores de JS es casual.

En el ejemplo siguiente se muestra el registro dinámico del componente Quote anterior con "quote" como identificador.

  • En una Blazoraplicación web, modifique la llamada a AddInteractiveServerComponents en el archivo del lado servidor Program:

    builder.Services.AddRazorComponents()
        .AddInteractiveServerComponents(options =>
        {
            options.RootComponents.RegisterForJavaScript<Quote>(identifier: "quote",
              javaScriptInitializer: "initializeComponent");
        });
    
  • En una aplicación Blazor Server, modifique la llamada a AddServerSideBlazor en el archivo Program:

    builder.Services.AddServerSideBlazor(options =>
    {
        options.RootComponents.RegisterForJavaScript<Quote>(identifier: "quote", 
            javaScriptInitializer: "initializeComponent");
    });
    
  • En una aplicación Blazor WebAssembly, llame a RegisterForJavaScript en RootComponents el archivo del lado cliente Program:

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

Asocie la función de inicializador con los parámetros de función name y parameters al objeto window. La función initializeComponent siguiente registra el nombre y los parámetros del componente registrado, solo como demostración.

wwwroot/jsComponentInitializers.js:

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

Represente el componente de JS en un elemento contenedor mediante el identificador registrado y pase los parámetros del componente según sea necesario.

En el ejemplo siguiente:

  • El componente Quote (identificador quote) se representa en el elemento quoteContainer cuando se llama a la función showQuote.
  • Se pasa una cadena de cita al parámetro Text del componente.

wwwroot/scripts.js:

async function showQuote() {
  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.'"
  });
}

Una vez cargado el script Blazor, cargue los scripts precedentes en la aplicación JS:

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

En el ejemplo anterior, el marcador de posición {BLAZOR SCRIPT} es el script Blazor.

En HTML, coloque el elemento contenedor de destino (quoteContainer). Para la demostración de esta sección, un botón desencadena la representación del componente Quote mediante una llamada a la función showQuote de JS:

<button onclick="showQuote()">Show Quote</button>

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

Al inicializar antes de representar cualquier componente, la consola de herramientas de desarrollo del explorador registra el identificador (name) y los parámetros (parameters) del componente Quote cuando se llama a initializeComponent:

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

Al seleccionar el botón Show Quote, el componente Quote se representa con la muestra de la cita almacenada en Text:

Cita representada en el explorador

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

Nota

rootComponents.add devuelve una instancia del componente. Llame a dispose en la instancia para publicarlo:

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

...

rootComponent.dispose();

En el ejemplo anterior se representa dinámicamente el componente raíz cuando se llama a la función showQuote()JS. Para representar un componente raíz en un elemento contenedor cuando se inicia Blazor, use un inicializador de JavaScript para representar el componente, como se muestra en el ejemplo siguiente.

El siguiente ejemplo se basa en el anterior, utilizando el componente Quote, el registro del componente raíz en el archivo Program y la inicialización de jsComponentInitializers.js. La función showQuote() (y el archivo script.js) no se usan.

En HTML, coloque el elemento contenedor de destino, quoteContainer2 en este ejemplo:

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

Con un inicializador de JavaScript, agregue el componente raíz al elemento contenedor de destino.

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

Para una aplicación web de Blazor:

export function afterWebStarted(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.'"
    });
}

Para una aplicación Blazor Server o Blazor WebAssembly:

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.'"
    });
}

Nota:

Para la llamada a rootComponents.add, use el parámetro blazor ( bminúsculas) proporcionado por el evento de inicio Blazor. Aunque el registro es válido cuando se usa el objeto Blazor (B mayúsculas), el enfoque preferido es usar el parámetro.

Para obtener un ejemplo avanzado con características adicionales, consulte el ejemplo de BasicTestApp del origen de referencia de ASP.NET Core (repositorio de GitHub dotnet/aspnetcore):

Nota

Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, use la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, vea Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Elementos Blazor personalizados

Use elementos de Blazor personalizados para representar de forma dinámica componentes Razor de otros marcos SPA, como Angular o React.

Elementos Blazor personalizados:

  • Use interfaces HTML estándar para implementar elementos HTML personalizados.
  • Elimine la necesidad de administrar manualmente el estado y el ciclo de vida de los componentes Razor raíz mediante las API de JavaScript.
  • Estas son útiles para introducir de forma gradual componentes Razor en proyectos existentes escritos en otros marcos SPA.

Los elementos personalizados no admiten contenido secundario ni componentes con plantilla.

Nombre del elemento

Según la especificación HTML, los nombres de etiquetas de elementos personalizados deben adoptar el formato con guiones siguiente:

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

Paquete

Agregue al archivo del proyecto de la aplicación una referencia al paquete para Microsoft.AspNetCore.Components.CustomElements.

Nota

Para obtener instrucciones sobre cómo agregar paquetes a aplicaciones .NET, consulte los artículos de Instalación y administración de paquetes en Flujo de trabajo de consumo de paquetes (NuGet documentación). Confirme las versiones correctas del paquete en NuGet.org.

Componente de ejemplo

Los siguientes ejemplos se basan en el componente Counter de la plantilla de proyecto 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 la aplicación web Blazor

Siga estos pasos para registrar un componente raíz como un elemento personalizado en una aplicación web Blazor.

Agregue el espacio de nombres Microsoft.AspNetCore.Components.Web a la parte superior del archivo del lado Program del servidor:

using Microsoft.AspNetCore.Components.Web;

Agregue un espacio de nombres para los componentes de la aplicación. En el ejemplo siguiente, el espacio de nombres de la aplicación es BlazorSample y los componentes se encuentran en la Components/Pages carpeta :

using BlazorSample.Components.Pages;

Modifique la llamada a para AddInteractiveServerComponents especificar el elemento personalizado con RegisterCustomElement en la RootComponents opción de circuito. En el ejemplo siguiente, se registra el componente Counter con el elemento HTML my-counter personalizado:

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

Registro de Blazor Server

Siga estos pasos para registrar un componente raíz como un elemento personalizado en una Blazor Server aplicación.

Agregue el espacio de nombres Microsoft.AspNetCore.Components.Web al principio del archivo Program:

using Microsoft.AspNetCore.Components.Web;

Agregue un espacio de nombres para los componentes de la aplicación. En el ejemplo siguiente, el espacio de nombres de la aplicación es BlazorSample y los componentes se encuentran en la Pages carpeta :

using BlazorSample.Pages;

Modifique la llamada a AddServerSideBlazor. Especifique el elemento personalizado con RegisterCustomElement en la RootComponents opción de circuito. En el ejemplo siguiente, se registra el componente Counter con el elemento HTML my-counter personalizado:

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

Registro de Blazor WebAssembly

Siga estos pasos para registrar un componente raíz como un elemento personalizado en una Blazor WebAssembly aplicación.

Agregue el espacio de nombres Microsoft.AspNetCore.Components.Web al principio del archivo Program:

using Microsoft.AspNetCore.Components.Web;

Agregue un espacio de nombres para los componentes de la aplicación. En el ejemplo siguiente, el espacio de nombres de la aplicación es BlazorSample y los componentes se encuentran en la Pages carpeta :

using BlazorSample.Pages;

Llame a RegisterCustomElement en RootComponents. En el ejemplo siguiente, se registra el componente Counter con el elemento HTML my-counter personalizado:

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

Usar el elemento personalizado registrado

Use el elemento personalizado con cualquier marco web. Por ejemplo, el elemento HTML personalizado my-counter anterior que representa el componente Counter de la aplicación se usa en una aplicación React con el marcado siguiente:

<my-counter></my-counter>

Para obtener un ejemplo completo de cómo crear elementos personalizados con Blazor, vea el componente CustomElementsComponent en el origen de referencia.

Nota

Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, use la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, vea Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Paso de parámetros

Pase parámetros al componente Razor como atributos HTML o como propiedades de JavaScript en el elemento DOM.

El componente Counter siguiente usa un parámetro IncrementAmount para establecer la cantidad de incremento del botón 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;
    }
}

Represente el componente Counter con el elemento personalizado y pase un valor al parámetro IncrementAmount como atributo HTML. El nombre del atributo adopta la sintaxis con guiones (increment-amount, no IncrementAmount):

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

Como alternativa, puede establecer el valor del parámetro como propiedad de JavaScript en el objeto de elemento. El nombre de la propiedad adopta la sintaxis de minúsculas y mayúsculas (incrementAmount, no IncrementAmount):

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

Puede actualizar los valores de los parámetros en cualquier momento mediante la sintaxis de atributos o propiedades.

Tipos de parámetros admitidos:

  • Con la sintaxis de propiedades de JavaScript, puede pasar objetos de cualquier tipo serializable JSON.
  • Con los atributos HTML, está limitado a pasar objetos de cadena, booleanos o tipos numéricos.

La compatibilidad experimental está disponible para crear elementos personalizados medianteMicrosoft.AspNetCore.Components.CustomElements NuGet package. Los elementos personalizados usan interfaces HTML estándar para implementar elementos HTML personalizados.

Advertencia

Las características experimentales se proporcionan con el fin de explorar la viabilidad de las características y es posible que no se incluyan en una versión estable.

Registre un componente raíz como un elemento personalizado:

  • En unaBlazor Server aplicación, modifique la llamada a AddServerSideBlazor en elProgram archivo para llamar a la llamada RegisterCustomElement en CircuitOptions.RootComponents:

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

    Nota:

    El ejemplo de código anterior requiere un espacio de nombres para los componentes de la aplicación (por ejemplo, using BlazorSample.Components.Pages;) en el archivo Program.

  • En una aplicación Blazor WebAssembly, llame a RegisterCustomElement en WebAssemblyHostBuilder.RootComponents en el archivo Program:

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

    Nota:

    El ejemplo de código anterior requiere un espacio de nombres para los componentes de la aplicación (por ejemplo, using BlazorSample.Components.Pages;) en el archivo Program.

Incluya la etiqueta <script> siguiente en el código HTML de la aplicación antes de la etiqueta de script Blazor:

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

Use el elemento personalizado con cualquier marco web. Por ejemplo, el elemento personalizado del contador anterior se usa en una aplicación React con el siguiente marcado:

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

Advertencia

La característica de elementos personalizados es actualmente experimental, no tiene soporte técnico y está sujeta a cambios o podría retirarse en cualquier momento. Agradecemos sus comentarios sobre la forma en que este enfoque concreto cumple sus requisitos.

Generación de componentes Angular y React

Genere componentes de JavaScript (JS) específicos del marco de trabajo a partir de componentes Razor para marcos web, como Angular o React. Esta funcionalidad no se incluye con .NET, pero la admite la compatibilidad para representar componentes Razor de JS. El ejemplo de generación de componentes JS de GitHub muestra cómo generar componentes Angular y React a partir de componentes Razor. Consulte el archivo README.md de la aplicación de ejemplo de GitHub para obtener información adicional.

Advertencia

Las características de los componentes Angular y React son actualmente experimentales, no tienen soporte técnico y están sujeta a cambios o podrían retirarse en cualquier momento. Agradecemos sus comentarios sobre la forma en que este enfoque concreto cumple sus requisitos.