Introducción a Web Components

Crea elementos HTML personalizables con su propia maquetación, estilos e interactividad.

introduccion-web-components

¿Qué es un Web Component?

Un Web Component es una tecnología de HTML que permite crear elementos HTML personalizados para encapsularlos y reutilizarlos en distintas aplicaciones web. A través de Web Components, los desarrolladores pueden definir elementos con comportamiento y estilo propios, sin preocuparse de conflictos con el resto del documento HTML.

Por ejemplo, en lugar de usar un componente HTML nativo como <button>, puedes definir un componente personalizado llamado <custom-button> que tenga un diseño y funcionalidad únicos.

Los Web Components se pueden descomponer básicamente en cuatro especificaciones:

  • Custom Elements: Permite definir nuevos elementos HTML personalizados con comportamientos específicos.
  • Shadow DOM: Ofrece encapsulamiento de estilo y estructura, aislando el componente del resto de la página.
  • HTML Templates: Permite definir estructuras HTML reutilizables que no se renderizan hasta ser utilizadas.
  • ES Modules: Define la inclusión y reuso de documentos JavaScript de una forma estándar.

Cómo definir un Web Component

Primero hay que añadir las etiquetas de nuestro Web Component dentro del código HTML de nuestra página:

<my-custom-element></my-custom-element>

Luego, para definir el Web Component, seguimos estos pasos en un archivo JavaScript:

  1. Crear una clase que extienda de HTMLElement o sus subclases (HTMLButtonElement, HTMLDivElement, etc.).
  2. Registrar el elemento personalizado utilizando customElements.define.
  3. Opcionalmente, usar Shadow DOM para encapsular el contenido.
// Definir el componente
class MyCustomElement extends HTMLElement {
constructor() {
super(); // Llamar al constructor del HTMLElement
const shadow = this.attachShadow({ mode: 'open' }); // Adjuntar Shadow DOM
const div = document.createElement('div');
div.textContent = '¡Hola desde Web Component!';
div.style.color = 'blue';
shadow.appendChild(div); // Agregar contenido al Shadow DOM
}
}
// Registrar el elemento
customElements.define('my-custom-element', MyCustomElement);

Si miras el código HTML de la página en el navegador verás el componente renderizado:

<my-custom-element>
#shadow-root (open)
<div style="color: blue;">¡Hola desde Web Component!</div>
</my-custom-element>

Funciones de ciclo de vida de un Web Component

Los Web Components tienen métodos de ciclo de vida que permiten reaccionar a cambios en su estado o en el DOM:

  • connectedCallback: Se ejecuta cuando el componente es agregado al DOM.
  • disconnectedCallback: Se ejecuta cuando el componente es eliminado del DOM.
  • attributeChangedCallback: Se ejecuta cuando uno de los atributos definidos cambia.
  • adoptedCallback: Se ejecuta cuando el componente se mueve a otro documento.

Ejemplo de un Web Component con funciones de ciclo de vida:

<lifecycle-example></lifecycle-example>

El código JavaScript:

class LifecycleExample extends HTMLElement {
constructor() {
super();
console.log('Constructor ejecutado');
}
connectedCallback() {
console.log('Elemento agregado al DOM');
}
disconnectedCallback() {
console.log('Elemento eliminado del DOM');
}
attributeChangedCallback(name, oldValue, newValue) {
console.log(`Atributo ${name} cambiado de ${oldValue} a ${newValue}`);
}
static get observedAttributes() {
return ['data-example']; // Especificar atributos que serán monitoreados
}
}
customElements.define('lifecycle-example', LifecycleExample);

Si cargas la página y miras la consola verás el orden en que se llama cada callback.

Otro ejemplo de Web Component

Veamos otro ejemplo práctico. En este caso creamos un contador que aumenta al hacer clic en un botón:

En tu HTML añadimos el componente:

<counter-component></counter-component>

Y la definición del componente en JavaScript:

class CounterComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.count = 0;
// Crear contenido del componente
this.shadowRoot.innerHTML = `
<style>
button {
background-color: #007BFF;
color: white;
border: none;
padding: 10px 20px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
</style>
<div>
<p>Contador: <span id="count">${this.count}</span></p>
<button id="increment">Incrementar</button>
</div>
`;
}
connectedCallback() {
this.shadowRoot.querySelector('#increment').addEventListener('click', () => {
this.count++;
this.shadowRoot.querySelector('#count').textContent = this.count;
});
}
disconnectedCallback() {
this.shadowRoot.querySelector('#increment').removeEventListener('click');
}
}
customElements.define('counter-component', CounterComponent);

Aquí puedes ver el ejemplo en acción:

Conclusión

Hemos visto qué es un Web Component, sus propiedades básicas y varios ejemplos. Este tipo de componentes pueden ser muy útiles en aplicaciones web, no requieren dependencias, son encapsulados y son fácilmentee reutilizables.