Condicionales x-if x-show y Ciclos x-for en Alpine JS
Índice de contenido
- Qué hacen realmente x-for y x-if/x-show en Alpine
- Renderizado vs ocultamiento: x-if vs x-show
-
Por qué Alpine exige el uso de
- x-if vs. x-show: Control de Renderizado en Alpine.js
- x-if vs x-show: cuándo usar cada uno
- 1. x-show: Manipulación CSS
- ️ 2. x-if: Eliminación del DOM
- Coste de renderizado y rendimiento práctico
- Casos donde x-show es más eficiente
- Cómo usar x-for en Alpine JS
- Qué es x-for y para qué sirve en Alpine JS
- Relación entre x-for y un forEach de JavaScript
- Cuándo conviene usar un loop en Alpine en lugar de JS puro
- Sintaxis básica de x-for con arrays
- La importancia del : por qué Alpine lo necesita
- Cuándo usar y cuándo no
- El error típico: colocar un
- x-for solo admite un elemento raíz: explicación y solución
- Buenas prácticas para combinar x-for y x-if
- Bucles, Condicionales y Objetos en Alpine.js
- Iterar objetos y listas complejas con x-for
- Caso real: listas de tareas, categorías o posts
- Reglas importantes: elemento raíz y claves únicas
- Preguntas frecuentes sobre el uso de x-for en Alpine JS
- Conclusión
En este artículo voy a enseñarte cómo funcionan realmente estas dos directivas, cuándo usarlas, cuándo NO usarlas juntas y qué hacer para que tus componentes —especialmente si usas Livewire— no muerdan el polvo que son el x-if y el x-fox.
Partimos de que sabemos como emplear Directiva x-bind en Alpine.js.
Qué hacen realmente x-for y x-if/x-show en Alpine
Renderizado vs ocultamiento: x-if vs x-show
Una cosa que casi nadie explica bien es que x-if no oculta nada: crea y destruye nodos.
Cuando lo probé por primera vez me llamó la atención que Alpine “saca” el elemento del DOM y lo vuelve a insertar cuando la condición cambia. Por eso, x-if cuesta más a nivel de rendimiento.
En cambio, x-show solo juega con el CSS, básicamente display: none, y listo. Por lo demás, el x-if y el x-show son equivalentes.
Si tu elemento puede estar en el DOM sin problema, x-show es casi siempre la mejor opción.
Por qué Alpine exige el uso de <template>
Tanto x-for como x-if exigen template como envoltorio, y aquí Alpine es bastante estricto.
Cuando probé a colocarlo directamente sobre un <div>, como haría en Vue, Alpine simplemente no lo reconoce o lo hace de manera incompleta.
Piensa en <template> como el “contenedor invisible” que Alpine necesita para manipular internamente el DOM sin romper tu estructura.
x-if vs. x-show: Control de Renderizado en Alpine.js
Ahora vamos a conocer la directiva x-if, que es similar a x-show pero con una diferencia de rendimiento fundamental, idéntica a la que existe en Vue.
1. Sintaxis de x-if
Para que x-if funcione correctamente, al igual que con x-for, Alpine requiere que la directiva envuelva el contenido en una etiqueta <template>.
<div x-data="{ open: false }">
<button @click="open=!open">Click!</button>
<span x-show="open">
Content... show
</span>
<template x-if="open">
<span>
Content... if
</span>
</template>
</div>x-if vs x-show: cuándo usar cada uno
- x-show: Es más eficiente si el elemento se mostrará y ocultará frecuentemente, ya que la renderización inicial del elemento es costosa, pero los cambios posteriores son rápidos (solo CSS).
- x-if: Es más costoso debido a que el browser tiene que volver a renderizar el elemento cada vez que la condición cambia a true y desmontarlo cuando es false.
1. x-show: Manipulación CSS
- Cuando la condición (open) es false, la directiva x-show simplemente actúa sobre el elemento inyectándole el estilo CSS display: none;.
- El elemento (el <span> con el texto "Content... show") permanece en el Árbol DOM.
- Alpine lo está ocultando, no eliminando. Es como si estuviera presente, pero invisible.
- Costo de rendimiento: Bajo, ya que solo se manipula una propiedad CSS.
️ 2. x-if: Eliminación del DOM
- Aquí es donde reside la diferencia fundamental, ya que x-if no oculta, sino que elimina o inserta el elemento en el DOM.
- Cuando open es false: El <span> con "Content... if" es removido completamente del DOM.
- El Template: El tag <template> no se renderiza como un elemento visual, sino que es una etiqueta especial que Alpine utiliza internamente como un "contenedor" del contenido que debe gestionar. Cuando la condición es falsa, el <span> hijo no aparece.
- Costo de rendimiento: Alto. Renderizar y quitar elementos del DOM es más costoso que cambiar una regla CSS.
Coste de renderizado y rendimiento práctico
Mi regla básica hoy es:
Situación Usa
El elemento debe existir siempre pero solo mostrarse x-show
El elemento depende totalmente de la condición para existir x-if
La condición cambia frecuentemente x-show
La condición rara vez cambia y el contenido es pesado x-if
En general, x-show es más “suave”, mientras que x-if es más “quirúrgico”.
Casos donde x-show es más eficiente
En prácticas reales —por ejemplo al mostrar/ocultar partes de un formulario— x-show es mucho mejor.
Pero cuando necesito condicionales dependientes de otra estructura (como listas filtradas por estado), x-if es la opción correcta.
Cómo usar x-for en Alpine JS
Cuando empecé a trabajar con Alpine JS, una de las cosas que más utilicé desde el principio fue el x-for, porque en prácticamente cualquier componente necesitas repetir elementos en pantalla. Lo bueno es que funciona de forma muy parecida al forEach de JavaScript, pero integrado directamente en el HTML y respetando toda la reactividad de Alpine.
La directiva x-for es una característica fundamental de los frameworks reactivos que nos permite crear un bloque de contenido HTML (un conjunto de etiquetas) basado en el tamaño de un array. Si tenemos un array de tres elementos, podemos hacer que cada uno se represente automáticamente, por ejemplo, dentro de una etiqueta <p>.
Qué es x-for y para qué sirve en Alpine JS
x-for es la directiva de Alpine JS que te permite iterar un array u objeto y renderizar un bloque HTML por cada elemento. Es la forma más rápida y limpia de crear listas dinámicas.
Relación entre x-for y un forEach de JavaScript
Si ya estás familiarizado con un forEach, entender x-for es casi inmediato:
- En JS recorres los datos en el script.
- En Alpine recorres los datos directamente en la vista.
Personalmente, cuando explico esto siempre digo lo mismo: “piensa en x-for como el for de toda la vida, pero incrustado en el HTML”.
Cuándo conviene usar un loop en Alpine en lugar de JS puro
Yo lo uso cuando:
- necesito renderizar HTML basado en datos reactivos;
- quiero mantener la interfaz limpia sin manipular el DOM a mano; trabajo con Livewire, porque ahí casi siempre estoy iterando objetos completos.
Sintaxis básica de x-for con arrays
La sintaxis es similar a la de un for-each en JavaScript:
<div x-data="{todos:[ 'Sacar la basura', 'programar un rato', 'durar en el trabajo']}">
<template x-for="t in todos">
<p x-text="t"></p>
</template>
</div>- Defino el array dentro de x-data.
- Uso <template> como contenedor del loop.
- Dentro pongo el HTML que quiero repetir.
- t representa cada elemento.
La importancia del <template>: por qué Alpine lo necesita
- Aquí viene una de esas cosas que muchos principiantes pasan por alto.
- El <template> es una etiqueta especial de HTML que NO se renderiza. Y Alpine lo usa para manipular el contenido sin contaminar tu árbol DOM.
- El template actúa como un “contenedor invisible”. Alpine lo analiza, clona su contenido y luego sí crea los elementos visibles.
Cuándo usar <template> y cuándo no
- Úsalo siempre cuando vayas a usar x-for o x-if.
- Evítalo solo cuando la directiva vaya sobre un elemento que necesitas que exista en el DOM.
El error típico: colocar un <div> en lugar del template
Si haces esto:
<div x-for="item in items">
<p x-text="item"></p>
</div>No va a funcionar como esperas. Alpine exige <template> cuando se trata de directivas lógicas.
x-for solo admite un elemento raíz: explicación y solución
Este es uno de los errores más comunes que veo.
<template x-for="t in todos">
<p x-text="t"></p>
<span>No se renderiza</span>
</template>Aquí Alpine va a quejarse.
Buenas prácticas para combinar x-for y x-if
Por qué no deben ir en el mismo nodo (y qué hacer en su lugar)
Aquí voy con algo que descubrí pegándome con Alpine más de una vez:
NO coloques x-for y x-if en el mismo elemento.
- Nunca.
- Jamás.
- Ni en días festivos.
Si haces esto:
<div x-for="t in todos" x-if="t.completed">…Alpine se queda en modo “¿y ahora qué hago?”.
La solución es simple: pon el x-if antes o después, no junto.
Yo lo uso así:
<template x-for="t in todos">
<template x-if="t.completed">
<span>Completado</span>
</template>
</template>O así:
<template x-if="shouldShow">
<template x-for="t in todos">Bucles, Condicionales y Objetos en Alpine.js
Quiero mostrarte de manera demostrativa cómo puedes emplear la directiva x-for (el bucle for) junto con condicionales (x-if) y, especialmente, cómo iterar sobre objetos en lugar de primitivas (textos, enteros, etc.).
⚠️ Regla de Oro: x-for y x-if
Lo primero y más importante: si quieres emplear x-for y x-if juntos, te aconsejo que no los coloques al mismo nivel.Si necesitas una condición previa para mostrar el loop completo, colócala en un contenedor que encapsule todo el x-for. Si la condición es interna a cada elemento, colócala dentro del cuerpo del loop. Nunca deben estar en la misma etiqueta.
Esto es crucial, especialmente al trabajar con Livewire, ya que siempre estaremos iterando listados de objetos (categorías, posts, entidades de todos) y necesitaremos aplicar condicionales (por ejemplo, marcar un checkbox si un todo está completed).
Para iterar sobre una lista de objetos, se define la data como un array de objetos.
<div
x-data="{ todos:[ {completed:true, task:'Todo 1'}, {completed:false, task:'Todo 2'}, {completed:true, task:'Todo 3'} ] }">
<template x-for="t in todos">
<p>
<template x-if="t.completed">
<span>
Completed
</span>
</template>
<template x-if="!t.completed">
<span>
Incompleted
</span>
</template>
<span x-text="t.task"></span>
</p>
</template>
</div>Esto funciona perfecto… siempre y cuando respetes el elemento raíz, que es el siguiente punto:
- x-for="t in todos": Itera el array todos, donde t es el objeto de la tarea en cada ciclo.
- x-if="t.completed": Como completed es un valor booleano, podemos evaluar la condición directamente (equivale a t.completed == true).
Iterar objetos y listas complejas con x-for
Caso real: listas de tareas, categorías o posts
En aplicaciones reales rara vez iteras strings.
Lo normal es iterar objetos: tareas, categorías, posts, usuarios, etc.
Cuando empecé a trabajar componentes un poco más reales me di cuenta de que Alpine se comporta perfecto con objetos siempre que mantengas el patrón:
<template x-for="t in todos" :key="t.id">Reglas importantes: elemento raíz y claves únicas
Un error muy común (y que yo mismo cometí más de una vez) es no darle un único elemento raíz a cada iteración.
Si haces esto:
<template x-for="t in todos">
<p x-text="t.task"></p>
<span>No se va a renderizar</span>
</template>Solo se renderizará el primer elemento, el resto desaparece.
Alpine lo dice clarísimo: un solo elemento raíz por iteración, como un <div>, <p>, <li>, etc.
Preguntas frecuentes sobre el uso de x-for en Alpine JS
- ¿Por qué x-for requiere un template?
- Porque Alpine necesita un contenedor lógico que no se renderice.
- ¿Puedo usar x-if y x-for juntos?
- Sí, pero no en el mismo nivel.
- ¿Qué hago si necesito varios elementos dentro del loop?
- Encapsúlalos en un único nodo raíz.
- ¿Cómo iterar objetos?
- Exactamente igual que arrays, pero accediendo a propiedades dentro del loop.
- ¿Puedo usar x-else en Alpine?
- No. No existe. Se resuelve con dos x-if.
- ¿Puedo ordenar o filtrar dentro de x-for?
- Sí, pero conviene hacerlo en tu estado, no directamente en el markup.
- ¿x-if afecta al rendimiento?
- Sí, porque crea o destruye elementos del DOM.
- ¿Qué pasa si no uso template con x-if o x-for?
- Alpine no ejecutará la directiva correctamente, o lo hará parcialmente.
Conclusión
x-for es una de las herramientas más potentes y sencillas de Alpine JS. Una vez entiendas el papel del <template>, las limitaciones del nodo raíz y la correcta relación con x-if, ya puedes construir interfaces completas y reactivas sin escribir una sola línea de JavaScript extra.
Y si trabajas con Livewire, todavía más: es un combo muy natural para iterar objetos y representar estados en pantalla de forma declarativa.
Combinar x-for y x-if correctamente en Alpine JS no es solo cuestión de sintaxis: tiene truco, y Alpine exige orden. Después de romper algunos componentes —y ver cómo Alpine hacía cosas rarísimas— terminé con estas reglas:
- Nunca mezcles x-for y x-if en el mismo nodo.
- Usa always un solo elemento raíz.
- x-show para mostrar/ocultar; x-if para crear/destruir.
- template siempre que uses x-if o x-for.
- Múltiples x-if en vez de x-else.
Siguiente paso, el uso de x-ref en Alpine.
Acepto recibir anuncios de interes sobre este Blog.
Vamos a conocer el uso del condicional en Alpine JS mediante el x-if al igual que el x-show y cuando usar uno o el otro, el uso de x-for para los listados y el uso de la etiqueta template como elemento HTML fundamental para usar estas directivas.