Lección 16: Componentes | Curso JavaScript

Lección 16: Componentes

Es común, cuando desarrollamos un App o sitio web, encontrarnos con repeticiones de bloques HTML cuyas funcionalidades son clónica. Para simplificar el desarrollo, y centralizar la lógica, se tiende a crear componentes. Un técnica de arquitectura donde divides las funcionalidades en fragmentos reutilizables formado por la triada de HTML, CSS y JavaScript.

Con la llegada de los módulos, que hemos aprendido en la lección anterior, nos permite crear componentes nativamente (Vainilla) sin recurrir a frameworks externos como ReactJS, VueJS o Angular. Se denomina Custom Elements.

Custom Elements o Componentes personalizados

A partir de la siguiente etiqueta que he inventado, con un atributo para indicar la cifra, puedo formatear un precio con un doble decimal y el símbolo del euro.

<price-component amount="34.2"></price-component>

34.20 €

¿Cómo es posible? En JavaScript solo necesito crear una clase que herede de HTMLElement y registrarlo con customElements.

// Clase del componente
class PriceComponent extends HTMLElement {

    constructor() {
        super();
        this.render();
    }

    render() {
        this.textContent = `${parseFloat(this.getAttribute("cantidad")).toFixed(2)} €`;
    }
}

// Al registrar definimos el nombre del componente, que siempre debe estar formado por dos palabras como mínimo.
customElements.define("price-component", PriceComponent);

Puedes crear todos los que haga uso tu sitio para todo tipo de funcionalidades: filtrado, formateo, cálculos, conexiones asíncronas… Aunque estamos limitados a la hora de incluir HTML. Para ello incluiremos una plantilla HTML.

Componentes personalizados con plantilla HTML

En el siguiente ejemplo puedes ver como se ha declarado un componente con el objetivo de representar algunas fichas de personales históricos. Son totalmente configurables a partir de sus atributos y hacen uso de una plantilla para definir la estructura HTML.

<card-component
    name="Lope de Vega"
    country="Spain"
    avatar="https://upload.wikimedia.org/wikipedia/commons/thumb/1/1d/Lope_de_vega.JPG/640px-Lope_de_vega.JPG"
></card-component>

<card-component
    name="Francisco de Quevedo "
    country="Spain"
    avatar="https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Retrato_de_Francisco_de_Quevedo%2C_after_an_original_attributed_to_John_Vanderham.jpg/640px-Retrato_de_Francisco_de_Quevedo%2C_after_an_original_attributed_to_John_Vanderham.jpg"
></card-component>

<template id="card">
    <div>
        <div class="card">
            <h2 class="card__name"></h2>
            <h3 class="card__country"></h3>
            <p>
                <img class="card__avatar" src="" alt="Avatar">
            </p>
        </div>
    </div>
</template>

Escritores en escritores

La única diferencia es que en el momento de renderizar capturaremos el contenido de la plantilla e iremos modificando las etiquetas que nos haga falta.

class CardComponent extends HTMLElement {

    constructor() {
        super();
        this.render();
    }

    render() {
         // Obtenemos el contenido de la plantilla
         const template = document.querySelector("template#card").content.firstElementChild;
         const miTemplate = template.cloneNode(true);
         // Modificamos el HTML de la plantilla
         miTemplate.querySelector(".card__name").textContent = this.getAttribute("name");
         miTemplate.querySelector(".card__country").textContent = this.getAttribute("country");
         miTemplate
             .querySelector(".card__avatar")
             .setAttribute("src", this.getAttribute("avatar"));
         // Insertamos el HTML modificado
         this.appendChild(miTemplate);
    }
}

customElements.define("card-component", CardComponent);

Sobre la base que hemos definido, ya podemos construir componentes a medida todo lo complejo que se nos pase por la cabeza.

Componentes personalizados reutilizables

Si no quieres depender de una <template>, y que tu componente pueda ser llamado en todas la páginas, debes introducir el HTML dentro de tu JavaScript.

A continuación puedes ver una adaptación del código anterior.

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8"/>
         <title>Ejemplo reutilizable</title>
    </head>
    <body>

    <card-component
        name="Lope de Vega"
        country="Spain"
        avatar="https://upload.wikimedia.org/wikipedia/commons/thumb/1/1d/Lope_de_vega.JPG/640px-Lope_de_vega.JPG"
    ></card-component>

    <card-component
        name="Francisco de Quevedo "
        country="Spain"
        avatar="https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Retrato_de_Francisco_de_Quevedo%2C_after_an_original_attributed_to_John_Vanderham.jpg/640px-Retrato_de_Francisco_de_Quevedo%2C_after_an_original_attributed_to_John_Vanderham.jpg"
    ></card-component>

    <script>
     class CardComponent extends HTMLElement {

         constructor() {
             super();
             this.render();
         }

         render() {
             // Obtenemos el contenido de la plantilla
             const miTemplate = document.createElement("div");
             miTemplate.innerHTML = `
                 <div class="card">
                     <h2 class="card__name"></h2>
                     <h3 class="card__country"></h3>
                     <p><img class="card__avatar" src="" alt="Avatar"></p>
		 </div>`;
             // Modificamos el HTML de la plantilla
             miTemplate.querySelector(".card__name").textContent = this.getAttribute("name");
             miTemplate.querySelector(".card__country").textContent = this.getAttribute("country");
             miTemplate
                 .querySelector(".card__avatar")
                 .setAttribute("src", this.getAttribute("avatar"));
             // Insertamos el HTML modificado
             this.appendChild(miTemplate);
         }
     }

     customElements.define("card-component", CardComponent);
    </script>
    </body>
</html>
Actividad 1

Crea un componente personalizado que limite un texto, por muy largo que sea, a 5 palabras. Debe terminar con tres puntos (...).

Actividad 2

Crea un componente que muestre una imagen aleatoria. Si quieres darle más personalizacion, permite que se pueda incluir un atributo con la temática de la imagen.

Actividad 3

Crea un componente para ver el avatar de un usuario de GitHub. Debe permitir incluir el nombre de usuario y el tamaño del avatar.

Ayudate del siguiente url: https://github.com/{usuario}.png.

Esta obra está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional.

Atribución/Reconocimiento-NoComercial-SinDerivados 4.0 Internacional

¿Me ayudas?

No te sientas obligado a realizarme una donación, pero cada aportación me ayuda a mantener el sitio en activo para que continúe existiendo y me motiva a continuar creando nuevo contenido.

Comprame un café
Pulsa sobre la imagen
  • 1 café: Se mantiene el dominio durante 4 meses.
  • 2 cafés: Se liquida 1 mes del Servidor Web.
  • 3 cafés: Se paga 1 mes de Newsletter.

Comentarios

{{ comments.length }} comentarios

Nuevo comentario

Nueva replica  {{ formatEllipsisAuthor(replyComment.author) }}

Acepto la política de Protección de Datos.

Escribe el primer comentario