> Manuales > Manual de Alpine.js

Conoce la directiva x-data de Alpine.js, que define los datos de un componente de Alpine pero también activa todas las características que nos ofrece esta librería.

Directiva x-data de Alpine.js

En este artículo vamos a explicar la directiva x-data de Alpine.js. Se trata de uno de los conocimientos más esenciales dentro de esta librería Javascript, ya que nos permite iniciar cualquier tipo de funcionalidad en la que deseemos trabajar con Alpine.

Qué es x-data

x-data es la directiva más importante de Alpine.js, ya que toda funcionalidad que quieras desarrollar en Alpine comienza con ella. Dicho de otra manera, x-data define que un pedazo cualquiera de nuestro HTML será un componente de Alpine.

Funciona como cualquier otra directiva, indicándola como si fuese un atributo HTML. Dentro de la directiva x-data lo común es declarar el estado del componente, esto es, los datos que vamos a manejar dentro del componente, así como posibles métodos para implementar su funcionalidad.

Concepto de componente en Alpine

En este punto inicial del manual de Alpine.js, y ya que hemos mencionado la palabra "componente", deberíamos definir exactamente qué se considera un componente dentro de Alpine.

Aclarar este punto es importante porque en Alpine el concepto de componente es ligeramente distinto al que podemos tener en mente si hemos usado librerías como React, Vue o Web Components. En esas librerías un componente generalmente se define mediante código JavaScript, creando una especie de nueva "etiqueta" que podremos luego utilizar en el HTML para implementar la utilidad para la que se ha construido ese componente.

Los componentes en React y similares, por tanto, se implementan en el Javascript, definiendo dos partes fundamentales:

Sin embargo, en Alpine el modo de trabajo es un poco diferente, ya que es común definir nuestra funcionalidad dentro del propio HTML. Es por ello que un componente varía un poco en su concepto.

Cómo implementar la directiva x-data

Habiendo explicado estos conceptos teóricos vamos a ver ahora un poco de código para implementar la directiva x-data.

Lo más común es utilizar la directiva x-data para algún tipo de información que sea importante para el componente.

<div x-data="{edad: 18}"></div>

Una vez que tenemos un dato almacenado en el componente, podemos utilizarlo para cualquier tipo de operación. Para poder hacer alguna cosa ese dato necesitamos aprender otras directivas de Alpine. No obstante, podemos ver un ejemplo sencillo aquí:

<div x-data="{edad: 18}">
  Tienes <span x-text="edad"></span> años.
</div>

En este caso estamos usando el valor de la edad para mostrarlo dentro del propio componente.

x-data es necesario para usar cualquier comportamiento de Alpine

Es importante notar que, para cualquier cosa que necesitemos hacer con Alpine en un bloque HTML, se requiere haber utilizado x-data en ese bloque HTML.

Por ejemplo, imaginemos que queremos utilizar la directiva x-on, para la definición de manejadores de eventos en un lugar de la página.

<p x-on:click="console.log('hola')">Haz click y no pasará nada</p>

Si este párrafo no de encuentra dentro de un bloque marcado con x-data, esa directiva no aportará ningún valor para Alpine y el navegador simplemente la ignorará.

Por eso, si queremos que ese manejador funcione debemos meterlo en un bloque x-data, incluso aunque no tengamos nada que almacenar.

<p x-data="{}" x-on:click="console.log('hola')">Haz click y verás un mensaje en la consola</p>

En estos casos en los que no tenemos ningún dato sería más conveniente coloquemos solamente el atributo sin asignar valor alguno.

<p x-data x-on:click="console.log('hola')">Haz click y verás un mensaje en la consola</p>

Ámbito de los x-data

A la hora de hacer componentes en Alpine podemos basarnos en otros componentes, que tendrían sus propios x-data. Es por ello que es perfectamente posible anidar bloques de HTML con sus propias directivas x-data.

Ten en cuenta que el ámbito más interno de un x-data puede sobreescribir valores de un ámbito de x-data superior.

En realidad esto no debería sorprenderte mucho, ya que funciona igual que el ámbito de las variables en funciones en Javascript y otros lenguajes.

En el siguiente ejemplo queremos demostrar la manera de anidar componentes, con sus propios x-data en los que pueden haber datos en común.

<div x-data="{ciudad: 'Valencia', pais: 'España'}">
  <p>En este ámbito puedo acceder al país <span x-text="pais"></span> y la ciudad <span x-text="ciudad"></span>.</p>
  <div x-data="{comunudadAutonoma: 'Comunidad Valenciana', ciudad: 'Alicante'}">
    <p>En este ámbito puedo acceder al país <span x-text="pais"></span> y la comunidad autónoma <span x-text="comunudadAutonoma"></span> y la ciudad <span x-text="ciudad"></span>.</p>
  </div>
</div>

Si ejecutas este ejemplo verás este texto:

En este ámbito puedo acceder al país España y la ciudad Valencia.

En este ámbito puedo acceder al país España y la comunidad autónoma Comunidad Valenciana y la ciudad Alicante.

Esto nos demuestra que:

Si este no es el comportamiento que necesitas para tus aplicaciones y, en cambio, deseas compartir datos entre componentes sin que se sobreescriben, entonces es mejor que utilices los mecanismos de $store proporcionados por el propio Alpine. Los veremos más adelante.

Cómo almacenar funcionalidad en x-data

Hasta el momento hemos visto los mecanismos para almacenar datos en el componente, sin embargo también puedes almacenar métodos que contengan el código JavaScript necesario para realizar comportamientos dinámicos. Esto puede ser muy necesario cuando tienes que implementar cualquier tipo de cálculo u operación un poco más compleja que una simple asignación de valores.

Por ejemplo, ahora vamos a ver un componente que muestra la hora actual. Para conseguir mostrar la hora en un formato legible por humanos tenemos que ejecutar un poco de código JavaScript. Lo ideal es que introduzcamos ese código dentro de una función, o mejor dicho, un método del objeto de datos almacenado en x-data.

Esa función contendrá todo el código necesario para conseguir componer la hora de una manera legible. Pero además en nuestro ejemplo queremos crear un botón que actualice la hora mostrada en la página cada vez que se haga clic sobre él.

El código de nuestro componente se puede ver a continuación.

<div x-data="{ 
    dateTime: new Date(Date.now()), 
    format() {      
      let options = {
          hour: '2-digit',
          minute: '2-digit',
          second: '2-digit',
          hour12: false
      };
      return this.dateTime.toLocaleTimeString('es-ES', options);
    },
    update() {
      this.dateTime = new Date(Date.now());
    }
  }">
    <span x-text="format()"></span>
    <button x-on:click="update()">Actualizar</button>
  </div>

Como puedes apreciar, cuando empezamos a poner mayor cantidad de código dentro del objeto que asignamos a x-data, conviene formatear un poco más el valor del atributo, porque verlo todo en la misma línea sería completamente inentendible e impactaría negativamente en el mantenimiento de nuestro código. De todos modos, esto es solo un medio de proceder porque en Alpine podemos separar perfectamente todo ese código de un x-data a un bloque <script>, lo que aportará diversas ventajas como syntax highlight, posiblidad de reutilización del código y la separación del Javascript a un bloque independiente del propio HTML, lo que mejora el mantenimiento también de los componentes.

En nuestro ejemplo cuando mostramos el texto con la hora llamamos al método formato(). Además cuando se define el manejador de eventos para el botón se invoca el método update(). Ambos métodos están definidos en el objeto declarado en x-data.

Conclusión

Con lo que hemos visto hasta este momento sobre x-data tienes suficiente para disponer de un conocimiento bastante amplio sobre las cosas que puedes hacer en Alpine con esta directiva. De momento vamos a dar una pausa por aquí y en los próximos artículos continuaremos conociendo en detalle otras directivas de Alpine.js.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual