Skip to content

Componentes y scopes

Cada bloque con x-data es un componente independiente con su propio scope de datos y lógica.

Un componente en Alpine.js es cualquier elemento que tenga la directiva x-data. Cada componente tiene su propio estado y lógica, y no interfiere con otros componentes a menos que se comuniquen explícitamente.

Componente básico
<div x-data="{ abierto: false }">
<button @click="abierto = !abierto">Abrir/Cerrar</button>
<div x-show="abierto">Contenido del componente</div>
</div>

Puedes anidar componentes, y cada uno tendrá su propio scope. Los datos de un componente padre no son accesibles directamente desde un hijo, y viceversa.

Componentes anidados
<div x-data="{ padre: 'Padre' }">
<span x-text="padre"></span>
<div x-data="{ hijo: 'Hijo' }">
<span x-text="hijo"></span>
<!-- Aquí no puedes acceder a 'padre' directamente -->
</div>
</div>

Para comunicarte entre componentes puedes usar eventos personalizados con $dispatch y escucharlos en el padre con x-on o @:

Comunicación entre componentes
<!-- Hijo -->
<div x-data>
<button @click="$dispatch('mensaje', { texto: '¡Hola, padre!' })">Enviar mensaje</button>
</div>
<!-- Padre -->
<div @mensaje.window="alert($event.detail.texto)"></div>

Puedes referenciar elementos dentro de un componente usando x-ref y acceder a ellos con $refs:

Uso de x-ref y $refs
<div x-data="{ enfocar() { this.$refs.input.focus() } }">
<input x-ref="input" type="text" />
<button @click="enfocar()">Foco</button>
</div>

Cada componente tiene su propio scope. Si declaras dos componentes en la misma página, sus datos no se mezclan:

Scopes independientes
<div x-data="{ valor: 1 }">
<button @click="valor++">Aumentar</button>
<span x-text="valor"></span>
</div>
<div x-data="{ valor: 10 }">
<button @click="valor++">Aumentar</button>
<span x-text="valor"></span>
</div>
🐝