Skip to main content

Crear componentes web Lightning

Objetivos de aprendizaje

Después de completar esta unidad, podrá:

  • Describir el contenido de cada archivo de componente.
  • Crear métodos de JavaScript para un componente web Lightning.
  • Utilizar enlaces de ciclo de vida en el JavaScript del componente.

Tiempo de juego

Supongamos que quiere construir un elemento para mostrar datos que sea independiente de un objeto específico de Salesforce. Un buen ejemplo sería el componente productCard en el repositorio de muestra de bicicletas eléctricas. Examinemos ese componente de tarjeta y creemos nuestra propia versión desde cero para que pueda ver cómo evoluciona hasta convertirse en un verdadero componente web Lightning. Entenderá rápidamente los fundamentos al crear las partes de un componente y explorar más ejemplos.

Entremos en una organización

En esta unidad desarrollaremos un componente web Lightning utilizando Visual Studio Code con la extensión de Salesforce.

Qué necesitará

Como explicamos en la primera unidad, para continuar debe estar familiarizado con Salesforce DX. Para completar esta unidad, necesita:

  • Visual Studio Code (VS Code) con el paquete de extensiones de Salesforce
  • Salesforce CLI

Para cumplir con los requisitos, complete el Inicio rápido: Componentes Web Lightning.

Un vistazo al archivo HTML

Todos los archivos HTML del componente web Lightning incluyen la etiqueta template. La etiqueta template contiene el HTML que define la estructura de su componente. Veamos el HTML para obtener una versión simplificada del componente productCard del repositorio de bicicletas eléctricas.

Continúe con estos ejemplos copiándolos en VS Code.

  1. Cree un proyecto seleccionando SFDX: Crear proyecto en la paleta de comandos de VS Code. Acepte la plantilla estándar y asígnele el nombre de proyecto bikeCard.
  2. En force-app/main/default, haga clic con el botón derecho en la carpeta lwc y seleccione SFDX: Crear componente web Lightning.
  3. Ingrese app (aplicación) como nombre del nuevo componente.
  4. Presione Enter (Intro) y, luego, Enter (Intro) de nuevo para aceptar la opción predeterminada force-app/main/default/lwc.
  5. Pegue lo siguiente en app.html (y sustituya todo HTML anterior del archivo).
    <template>
      <div>
        <div>Name: {name}</div>
        <div>Description: {description}</div>
        <div>Category: {category}</div>
        <div>Material: {material}</div>
        <div>Price: {price}</div>
        <div><img src={pictureUrl} alt={name}/></div>
      </div>
    </template>
    Los identificadores entre llaves {} están vinculados a los campos del mismo nombre en la clase de JavaScript correspondiente.
  6. Pegue lo siguiente en app.js.
    import { LightningElement } from 'lwc';
    export default class App extends LightningElement {
      name = 'Electra X4';
      description = 'A sweet bike built for comfort.';
      category = 'Mountain';
      material = 'Steel';
      price = '$2,700';
      pictureUrl = 'https://s3-us-west-1.amazonaws.com/sfdc-demo/ebikes/electrax4.jpg';
    }
  7. Guarde los archivos.

Ahora juguemos con un ejemplo real. Supongamos que desea mostrar datos, pero sabe que pueden tardar cierto tiempo en cargarse. No quiere que el usuario se preocupe por no saber qué ocurre. Puede utilizar las directivas condicionales lwc:if y lwc:else dentro de la plantilla para determinar qué elementos visuales se renderizan.

  1. Pegue lo siguiente en app.html. El contenido de la etiqueta div "display" no aparecerá hasta que el valor de ready sea true (verdadero) en el archivo HTML.
    <template>
      <template lwc:if={ready}>
        <div id="display">
          <div>Name: {name}</div>
          <div>Description: {description}</div>
          <div>Category: {category}</div>
          <div>Material: {material}</div>
          <div>Price: {price}</div>
          <div><img src={pictureUrl} alt={name}/></div>
        </div>
      </template>
      <template lwc:else>
        <div id="waiting">Loading…</div>
      </template>
    </template>
  2. Pegue lo siguiente en app.js. Esto mantiene nuestros valores de datos y activa un temporizador de 3 segundos. Al cabo de 3 segundos debería aparecer el contenido. (Evidentemente, esto es solo para hacer pruebas).
    import { LightningElement } from 'lwc';
    export default class App extends LightningElement {
      name = 'Electra X4';
      description = 'A sweet bike built for comfort.';
      category = 'Mountain';
      material = 'Steel';
      price = '$2,700';
      pictureUrl = 'https://s3-us-west-1.amazonaws.com/sfdc-demo/ebikes/electrax4.jpg';
      ready = false;
      connectedCallback() {
        setTimeout(() => {
          this.ready = true;
        }, 3000);
      }
    }
  3. Guarde los archivos.

Componentes web Lightning base

Como es lógico, no quiere construir todos sus componentes desde cero. Exploremos entonces cómo se utiliza un componente web Lightning base. Y evidentemente, hay muchos componentes, como tipos de campo, controladores de visualización, elementos de navegación y mucho más. Todos ellos aparecen en la Referencia de componentes.

Vamos a resaltar los detalles de la bicicleta. En el archivo app.html, sustituya las etiquetas div de material y categoría en el último ejemplo por el componente lightning-badge. Este es el HTML.

<template>
  <template lwc:if={ready}>
    <div id="display">
      <div>Name: {name}</div>
      <div>Description: {description}</div>
      <lightning-badge label={material}></lightning-badge>
      <lightning-badge label={category}></lightning-badge>
      <div>Price: {price}</div>
      <div><img src={pictureUrl} alt={name}/></div>
    </div>
  </template>
  <template lwc:else>
    <div id="waiting">Loading…</div>
  </template>
</template>

Guarde el archivo.

Las palabras Steel y Mountain aparecen como insignias. ¡Así de fácil!

Estructura de creación de componentes

Un componente simplemente necesita una carpeta y sus archivos con el mismo nombre. Los archivos quedan automáticamente vinculados por el nombre y la ubicación.

Archivos del componente en una carpeta

Todos los componentes web Lightning tienen un espacio de nombres que está separado del nombre de la carpeta por un guion. Por ejemplo, el marcado para el componente web Lightning con la aplicación de nombre de carpeta en el espacio de nombres c es <c-app>.

Sin embargo, la plataforma Salesforce no permite el uso de guiones en los nombres de archivos ni de carpetas del componente. ¿Qué ocurre si el nombre de un componente tiene varias palabras, como "mycomponent"? No se puede utilizar my-component en los nombres de la carpeta ni de los archivos, pero existe una solución práctica.

Utilice distinción entre mayúsculas y minúsculas para asignar a su componente el nombre myComponent. Los nombres de carpeta de componente de tipo camel case se corresponden con el tipo kebab-case (palabras separadas por guiones) en el marcado. En marcado, para hacer referencia a un componente con el nombre de carpeta myComponent, utilice <c-my-component>.

Por ejemplo, el repositorio de muestras LWC tiene la carpeta viewSource que incluye los archivos del componente viewSource. Cuando el componente de saludo hace referencia al componente viewSource en HTML, utiliza c-view-source.

De acuerdo. Veamos el código de JavaScript.

Trabajo con JavaScript

Aquí es donde se logra lo importante. Como vimos hasta el momento, los métodos de JavaScript definen qué se hace con las entradas, los datos, los eventos, los cambios de estado y otros elementos que hacen que funcione el componente.

El archivo JavaScript de un componente web Lightning debe incluir al menos este código, en el que MyComponent es el nombre que asigna a su clase de componente.

import { LightningElement } from 'lwc';
export default class MyComponent extends LightningElement {
}

La declaración export define una clase que amplía la clase LightningElement. Una de las mejores prácticas es poner el mismo nombre a la clase que al archivo de la clase de JavaScript, aunque no es un requisito obligatorio.

El módulo LWC

Los componentes web de Lightning utilizan módulos (se incorporaron módulos integrados en ECMAScript 6) para crear un paquete con las funciones principales y hacer que sean accesibles para el código de JavaScript en su archivo de componente. El módulo principal de los componentes web Lightning es lwc.

Empiece el módulo con la declaración import y especifique las funciones del módulo que utiliza su componente.

La declaración import indica que el código de JavaScript utiliza la función LightningElement del módulo lwc.

// import module elements
import { LightningElement} from 'lwc';
// declare class to expose the component
export default class App extends LightningElement {
  ready = false;
  // use lifecycle hook
  connectedCallback() {
    setTimeout(() => {
      this.ready = true;
    }, 3000);
  }
}
  • LightningElement es la clase base para los componentes web Lightning, lo que nos permite utilizar connectedCallback().
  • El método connectedCallback() es uno de nuestros enlaces de ciclo de vida. Obtendrá más información sobre los enlaces de ciclo de vida en la siguiente sección. Por ahora, recuerde que el método se activa cuando se inserta un componente en el Document Object Model (DOM). En este caso, activa el temporizador.

Enlaces de ciclo de vida

Los componentes web Lightning proporcionan métodos que le permiten "enlazar" su código con eventos críticos dentro del ciclo de vida de un componente. Estos eventos incluyen los momentos en los que un componente:

  • Es creado
  • Es agregado al DOM
  • Es representado en el navegador
  • Encuentra errores
  • Es eliminado del DOM

Responda a cualquiera de estos eventos del ciclo de vida utilizando métodos de devolución de llamadas. Por ejemplo, se invoca el método connectedCallback() cuando se inserta un componente en el DOM. Se invoca el método disconnectedCallback() cuando se elimina un componente del DOM.

En el archivo JavaScript que utilizamos para probar las directivas condicionales con las que se muestran elementos, utilizamos el método connectedCallback() para ejecutar el código de manera automática cuando se inserta el componente en el DOM. El código espera 3 segundos, luego establece ready como true.

import { LightningElement } from 'lwc';
export default class App extends LightningElement {
  ready = false;
  connectedCallback() {
    setTimeout(() => {
      this.ready = true;
    }, 3000);
  }
}
Nota

Al utilizar este ejemplo en un editor como VS Code, puede que se muestre una advertencia lint "Restricted async operation...." (operación de asincronización restringida...) para la función setTimeout(). Esta advertencia indica que está utilizando una operación de asincronización que a menudo se utiliza mal; retrasa un comportamiento en función del tiempo en lugar de esperar un evento. En este caso, setTimeout() es apropiado para demostrar un retraso de tiempo arbitrario y no debe dejar de utilizarla pese a la advertencia.

Tenga también en cuenta que utilizamos la palabra clave this. Debe estar familiarizado con el uso de palabras clave si ya escribió JavaScript; las palabras clave se comportan aquí igual que en otros entornos. La palabra clave this en JavaScript hace referencia al nivel superior del contexto actual. En este caso el contexto es esta clase (this). El método connectedCallback() asigna el valor para la variable ready de nivel superior. Es un buen ejemplo de cómo los componentes web Lightning permiten incorporar funciones de JavaScript en su desarrollo. Encontrará un vínculo con información útil sobre this en la sección Recursos.

Decoradores

Se suelen utilizar los decoradores en JavaScript para modificar el comportamiento de una propiedad o una función.

Para utilizar un decorador, impórtelo del módulo lwc y colóquelo antes de la propiedad o la función.

import { LightningElement, api } from 'lwc';
export default class MyComponent extends LightningElement{
  @api message;
}

Se pueden importar varios decoradores, pero cada propiedad o función concreta solo puede tener un decorador. Por ejemplo, una propiedad no puede tener los decoradores @api y @wire.

Estos son algunos ejemplos de decoradores de componentes web Lightning:

  • @api: marca un campo como público. Las propiedades públicas definen la API de un componente. Un componente propietario que utiliza el componente en su marcado HTML puede acceder a las propiedades públicas del componente. Todas las propiedades públicas son reactivas, lo que significa que el marco de trabajo observa la propiedad buscando cambios. Cuando el valor de la propiedad cambia, el marco de trabajo reacciona y vuelve a representar el componente.
Nota

Campo y propiedad son términos casi intercambiables. Un autor de un componente declara campos en una clase de JavaScript. Una instancia de la clase tiene propiedades. Para los consumidores del componente, los campos son propiedades. En un componente web Lightning solo los campos que el autor de un componente decora con @api estarán disponibles públicamente para los consumidores como propiedades de objeto.

  • @track: ordena al marco de trabajo que observe los cambios en las propiedades de un objeto o en los elementos de una matriz. Si se produce un cambio, el marco de trabajo vuelve a representar el componente. Todos los campos son reactivos. Si el valor de un campo cambia y el campo se utiliza en una plantilla (o en el método de obtención de una propiedad utilizada en una plantilla), el marco de trabajo vuelve a representar el componente. No es necesario decorar el campo con @track. Utilice @track únicamente si un campo contiene un objeto o una matriz y quiere que el marco de trabajo observe los cambios en las propiedades del objeto o en los elementos de la matriz. Si quiere cambiar el valor de la propiedad completa, no es necesario utilizar @track.
Nota

Hasta la versión Spring '20, había que utilizar @track para marcar los campos (también conocidos como propiedades privadas) como reactivos. Ya no es necesario hacer eso. Utilice @track solo para ordenar al marco de trabajo que observe los cambios en las propiedades de un objeto o en los elementos de una matriz. Es posible que algunos ejemplos heredados sigan utilizando @track cuando deben hacerlo, aunque no es problema porque el decorador no cambia la función ni rompe el código.

  • @wire: ofrece una manera sencilla de obtener y vincular datos desde una organización de Salesforce.

Aquí se incluye un ejemplo que utiliza el decorador @api para representar un valor de un componente (bicicleta) en otro (aplicación). La estructura del archivo tiene el siguiente aspecto:

Estructura de archivo de aplicación de muestra.

El componente de la aplicación utiliza el siguiente HTML.

<!-- app.html -->
<template>
  <div>
    <c-bike bike={bike}></c-bike>
  </div>
</template>

El componente de la aplicación utiliza el siguiente JavaScript.

// app.js
import { LightningElement } from 'lwc';
export default class App extends LightningElement {
  bike = {
    name: 'Electra X4',
    picture: 'https://s3-us-west-1.amazonaws.com/sfdc-demo/ebikes/electrax4.jpg'
  };
}

El componente de la bicicleta utiliza el siguiente HTML.

<!-- bike.html -->
<template>
  <img src={bike.picture} alt="bike picture" />
  <p>{bike.name}</p>
</template>

El componente de la bicicleta utiliza el siguiente JavaScript.

// bike.js
import { LightningElement, api } from 'lwc';
export default class Bike extends LightningElement {
  @api bike;
}

Estamos avanzando mucho, y ya trabaja con algunos códigos en VS Code. En la siguiente unidad, implementaremos algunos códigos y veremos en más detalle el entorno en el que se encuentran los componentes.

Recursos

Comparta sus comentarios de Trailhead en la Ayuda de Salesforce.

Nos encantaría saber más sobre su experiencia con Trailhead. Ahora puede acceder al nuevo formulario de comentarios en cualquier momento en el sitio de Ayuda de Salesforce.

Más información Continuar a Compartir comentarios