Plantillas en WebComponents

Cómo escribir código HTML a través de plantillas


Una de las razones principales por las que nos puede interesar crear un componente en nuestra página es para simplificar código. Crear componentes es una estupenda forma de unir el marcado (código HTML), estilo (código CSS) y funcionalidad (código Javascript) en un mismo sitio, de forma que sea mucho más cómodo de escribir para nosotros, los desarrolladores.

WebComponent: Modular

¿Por qué plantillas?

Una de las finalidades de un WebComponent es encapsular o aislar un código HTML más complejo dentro de una etiqueta HTML personalizada más sencilla, simplificando mucho su utilización, reduciendo la cantidad de código que tenemos que escribir y permitiendo reutilizarlo.

Una plantilla o template no es más que una porción de código, creada expresamente para reutilizarse en varias ocasiones y evitar repetir código. Es decir, algo que nos vendría genial en esta situación.

Formas de escribir HTML

Hay que recordar que un WebComponent, al fin y al cabo, es un fichero javascript .js, por lo que no podemos escribir código HTML directamente, sino que tenemos que utilizar alguna de las siguientes estrategias:

En los siguientes apartados, vamos a ver las diferentes formas que tenemos de escribir HTML en un componente a través de plantillas o templates.

El lenguaje HTML incorpora una etiqueta <template>, que no es más que una forma de definir una plantilla HTML de forma nativa. Con esta etiqueta podemos crear un fragmento de código (de forma aislada e independiente del documento) que utilizaremos más tarde, una o más veces.

Recalcar que el navegador no procesa el contenido de una etiqueta <template> (ni carga sus recursos, como scripts o imágenes). Además, si se define en el HTML, su rendimiento es mayor que otras alternativas como .innerHTML, ya que se evita todo el proceso dinámico de parseo y análisis de a marcado HTML.

En este artículo puedes profundizar un poco más sobre la etiqueta HTML <template>.

Ahora que conocemos la etiqueta <template>, podemos utilizar esta característica para crear un código HTML base, que posteriormente clonaremos y utilizaremos en nuestro componente.

La plantilla HTML se puede crear en nuestro código HTML de la siguiente forma:

<template>
  <div class="card">
    <h1>ManzDev</h1>
  </div>
</template>

Sin embargo, como estamos en un componente .js, lo ideal sería crearlo en Javascript para no estar añadiendo más archivos separados. Por esa razón, podemos crear la plantilla utilizando métodos del DOM que ya conocemos:

const template = document.createElement("template");
template.innerHTML = /* html */`
  <div class="card">
    <h1>ManzDev</h1>
  </div>`;

// Lógica Javascript del componente
class AppElement extends HTMLElement {
  connectedCallback() {
    const html = template.content.cloneNode(true);
    this.append(html);
  }
}

customElements.define("app-element", AppElement);
<app-element></app-element>

En este ejemplo hemos colocado el marcado en la parte superior del componente (fuera de la clase). De esta forma, se creará una sola vez y se utilizará cuando sea necesario.

Por otro lado, el uso de .content.cloneNode() sobre un template es importante, ya que estamos clonando el contenido del <template>, para posteriormente insertarlo en nuestro componente mediante .append(). El true indicado por parámetro es para hacer una clonación profunda (deep clone), es decir, clonar el elemento y todos sus elementos hijos.

En caso de establecerlo a false (o no indicarlo) se hará una clonación superficial (shallow clone), clonando sólo el elemento en cuestión (y no sus hijos, los cuales serán una referencia a los originales).

Es muy probable que este fragmento de código te recuerde a los ficheros SFC .vue de Vue. No es casualidad, ya que Evan You, creador de Vue, se basó en WebComponents para crear su framework.

Otra forma de escribir HTML en nuestros componentes sería elegir una librería Javascript que nos permita crear plantillas de forma más cómoda y rápida. Por ejemplo, utilizando la librería lit-html, librería independiente utilizada en la librería Lit.

Veamos un ejemplo análogo al anterior, utilizando esta librería:

import { html, render } from "https://cdn.jsdelivr.net/npm/[email protected]/+esm";
const template = html`
  <div class="card">
    <h1>ManzDev</h1>
  </div>`;

class AppElement extends HTMLElement {
  constructor() {
    super();
    render(template, this);
  }
}

customElements.define("app-element", AppElement);
<app-element></app-element>

Observa que hemos importado los ayudantes html y render de la librería lit-html. El primero sirve para crear las plantillas, mientras que el segundo ayuda a renderizar en el componente, pasándole la plantilla como primer parámetro y el elemento donde vamos a renderizarlo como segundo parámetro, que es this, el propio componente.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev