Saltar al contenido

Componentes Web

Los componentes web son una herramienta poderosa en el desarrollo web moderno, que permite a los desarrolladores crear elementos HTML reutilizables y encapsulados. En esta guía, profundizaremos en el mundo de los componentes web, proporcionando extensos ejemplos de código y explicaciones detalladas para ayudarte a dominar este aspecto esencial de JavaScript.

Introducción a los Componentes Web

Los componentes web son un conjunto de APIs de la plataforma web que te permiten crear nuevas etiquetas HTML personalizadas, reutilizables y encapsuladas para usar en páginas y aplicaciones web. Las tecnologías principales utilizadas en los componentes web son Custom Elements, Shadow DOM y HTML Templates.

Custom Elements

Los elementos personalizados definen nuevas etiquetas HTML y su comportamiento. Estos elementos se pueden usar como cualquier etiqueta HTML estándar, pero con comportamiento y estilos personalizados.


html
<div>
  <script>
    class MyElement extends HTMLElement {
      constructor() {
        super();
        this.attachShadow({ mode: 'open' });
        this.shadowRoot.innerHTML = '<p>Hello, World!</p>';
      }
    }
    customElements.define('my-element', MyElement);
  </script>
  <my-element></my-element>
</div>

Este fragmento de código demuestra cómo crear un elemento HTML personalizado llamado my-element. La clase MyElement extiende HTMLElement, adjunta un shadow DOM para encapsular su contenido e inserta un párrafo simple con el texto "Hello, World!".

Shadow DOM

Shadow DOM proporciona encapsulación para tus elementos personalizados. Te permite mantener los estilos y scripts limitados al propio elemento.


html
<div>
  <script>
    class ShadowElement extends HTMLElement {
      constructor() {
        super();
        let shadow = this.attachShadow({ mode: 'open' });
        shadow.innerHTML = `
          <style>
            p { color: blue; }
          </style>
          <p>Shadow DOM content</p>
        `;
      }
    }
    customElements.define('shadow-element', ShadowElement);
  </script>
  <shadow-element></shadow-element>
</div>

En este ejemplo, la clase ShadowElement extiende HTMLElement y adjunta una raíz shadow al elemento. El parámetro mode: 'open' especifica que el shadow DOM es accesible a través de JavaScript. Cuando mode se establece en 'open', la raíz shadow se puede acceder mediante la propiedad element.shadowRoot. Si mode se establece en 'closed', la raíz shadow no es accesible desde el exterior, lo que mejora la encapsulación y evita que scripts externos manipulen directamente el shadow DOM.

Dentro del shadow DOM, definimos algunos estilos y contenido HTML. Los estilos (en este caso, un párrafo con texto azul) están limitados al shadow DOM, asegurando que no afecten a ningún otro elemento en la página. Esta encapsulación es beneficiosa para crear componentes reutilizables con un estilo y comportamiento consistentes, independientemente del contexto en el que se utilicen.

WARNING

Utiliza estilos locales dentro del Shadow DOM para evitar la filtración de estilos y garantizar que los estilos del componente estén limitados.

HTML Templates

Las plantillas HTML te permiten definir fragmentos de HTML reutilizables que pueden ser instanciados en tiempo de ejecución.


html
<div>
  <template id="my-template">
    <style>
      p { color: red; }
    </style>
    <p>This is a template content</p>
  </template>
  <script>
    const template = document.getElementById('my-template').content;
    document.body.appendChild(template.cloneNode(true));
  </script>
</div>

Este ejemplo muestra cómo usar plantillas HTML. La etiqueta <template> contiene HTML y estilos que no se renderizan inmediatamente. El script clona el contenido de la plantilla y lo adjunta al cuerpo del documento, haciéndolo visible.

Creación de tu Primer Componente Web

Recorramos el proceso de creación de un componente web completamente funcional que pueda utilizarse en diferentes proyectos.

Paso 1: Definir el Componente

Crea una nueva clase que extienda HTMLElement.


html
<div>
  <script>
    class MyComponent extends HTMLElement {
      constructor() {
        super();
        const shadow = this.attachShadow({ mode: 'open' });
        shadow.innerHTML = 'Hello, World!'
      }
    }
    customElements.define('my-component', MyComponent);
  </script>
  <my-component></my-component>
</div>

Este fragmento establece la base para un componente web llamado my-component. Define una clase que extiende HTMLElement y adjunta un shadow DOM, preparándolo para una personalización posterior.

Paso 2: Agregar Estilos y Plantillas

Utiliza el Shadow DOM para encapsular estilos y plantillas.


html
<div>
  <script>
    class MyStyledComponent extends HTMLElement {
      constructor() {
        super();
        let shadow = this.attachShadow({ mode: 'open' });
        shadow.innerHTML = `
          <style>
            p { font-size: 20px; color: green; }
          </style>
          <p>This is my styled component!</p>
        `;
      }
    }
    customElements.define('my-styled-component', MyStyledComponent);
  </script>
  <my-styled-component></my-styled-component>
</div>

Este fragmento mejora my-styled-component agregando estilos limitados dentro del shadow DOM. El párrafo dentro del componente se estiliza con color verde y un tamaño de fuente aumentado.

Paso 3: Agregar Interactividad

Agrega JavaScript para hacer tu componente interactivo.


html
<div>
  <script>
    class InteractiveComponent extends HTMLElement {
      constructor() {
        super();
        this.attachShadow({ mode: 'open' });
        this.shadowRoot.innerHTML = `
          <style>
            p { font-size: 20px; }
          </style>
          <p>This is interactive!</p>
          <button>Click me</button>
        `;
        this.shadowRoot.querySelector('button').addEventListener('click', () => {
          this.shadowRoot.querySelector('p').textContent = 'You clicked!';
        });
      }
    }
    customElements.define('interactive-component', InteractiveComponent);
  </script>
  <interactive-component></interactive-component>
</div>

Este ejemplo muestra cómo hacer que un componente web sea interactivo. El InteractiveComponent incluye un botón que, al hacer clic, cambia el contenido de texto de un párrafo dentro del componente.

Técnicas Avanzadas de Componentes Web

Callbacks del Ciclo de Vida

Los elementos personalizados tienen callbacks del ciclo de vida que te permiten ejecutar código durante fases específicas de la vida de un elemento.


html
<div>
  <script>
    class LifecycleComponent extends HTMLElement {
      constructor() {
        super();
        this.attachShadow({ mode: 'open' });
      }
      connectedCallback() {
        this.shadowRoot.innerHTML = '<p>Element added to page.</p>';
      }
      disconnectedCallback() {
        console.log('Element removed from page.');
      }
    }
    customElements.define('lifecycle-component', LifecycleComponent);
  </script>
  <lifecycle-component></lifecycle-component>
</div>

Este fragmento demuestra el uso de callbacks del ciclo de vida en componentes web. El LifecycleComponent actualiza su contenido cuando se agrega a la página y registra un mensaje cuando se elimina.

Manejo de Cambios en Atributos

Reacciona a los cambios en los atributos de un elemento definiendo el array observedAttributes e implementando el método attributeChangedCallback.


html
<div>
  <script>
    class AttributeComponent extends HTMLElement {
      static get observedAttributes() {
        return ['data-text'];
      }
      constructor() {
        super();
        this.attachShadow({ mode: 'open' });
        this.shadowRoot.innerHTML = '<p></p>';
      }
      attributeChangedCallback(name, oldValue, newValue) {
        if (name === 'data-text') {
          this.shadowRoot.querySelector('p').textContent = newValue;
        }
      }
    }
    customElements.define('attribute-component', AttributeComponent);
  </script>
  <attribute-component data-text="Initial text"></attribute-component>
  <script>
    const element = document.querySelector('attribute-component');
    setTimeout(() => {
      element.setAttribute('data-text', 'Updated text');
    }, 2000);
  </script>
</div>

Este ejemplo muestra cómo manejar cambios en atributos dentro de un componente web. El AttributeComponent actualiza su contenido interno en función de los cambios en el atributo data-text.

Mejores Prácticas para Componentes Web

Usa el Shadow DOM Sabiamente

Encapsula estilos y scripts dentro del Shadow DOM para prevenir conflictos con otros elementos en la página.

Sigue las Convenciones de Nomenclatura

Los elementos personalizados deben contener un guion en su nombre para evitar conflictos con los elementos HTML estándar.

Mantén los Componentes Modulares

Crea componentes pequeños y reutilizables para mantener tu base de código mantenible y escalable.

Evita Estilos Globales

Utiliza estilos locales dentro del Shadow DOM para evitar la filtración de estilos y garantizar que los estilos del componente estén limitados.

Documentación y Pruebas

Documenta bien tus componentes y escribe pruebas para asegurar que funcionen como se espera en diferentes navegadores y casos de uso.

Conclusión

Los componentes web son una característica versátil y poderosa en el desarrollo web moderno, que permite la creación de elementos personalizados reutilizables y encapsulados. Al comprender y utilizar Custom Elements, Shadow DOM y HTML Templates, puedes crear aplicaciones web modulares, mantenibles y escalables. Esta guía te ha proporcionado el conocimiento y los ejemplos necesarios para comenzar con los componentes web, asegurando que puedas implementarlos de manera efectiva en tus proyectos.

Práctica

¿Cuál de las siguientes afirmaciones sobre los Componentes Web es correcta?

¿Te resulta útil?

Vista previa dual-run — compárala con las rutas Symfony en producción.