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.
- 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
.
- En force-app/main/default, haga clic con el botón derecho en la carpeta lwc y seleccione SFDX: Crear componente web Lightning.
- Ingrese
app
(aplicación) como nombre del nuevo componente.
- Presione Enter (Intro) y, luego, Enter (Intro) de nuevo para aceptar la opción predeterminada
force-app/main/default/lwc
.
- Pegue lo siguiente en app.html (y sustituya todo HTML anterior del archivo).Los identificadores entre llaves
<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>
{}
están vinculados a los campos del mismo nombre en la clase de JavaScript correspondiente.
- 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'; }
- 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.
- Pegue lo siguiente en app.html. El contenido de la etiqueta
div
"display" no aparecerá hasta que el valor deready
seatrue
(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>
- 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); } }
- 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.
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 utilizarconnectedCallback()
.
- 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); } }
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.
-
@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
.
-
@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:
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
- Guía del desarrollador de componentes web Lightning: Reactividad
- Guía del desarrollador de componentes web Lightning: Referencia (incluye directivas de plantillas HTML, decoradores y mucho más)
- Documentos web MDN: this