Saltearse al contenido

wire:loading

Los indicadores de carga son una parte importante de la creación de buenas interfaces de usuario. Proporcionan a los usuarios información visual cuando se realiza una petición al servidor, para que sepan que están esperando a que se complete un proceso.

Uso básico

Livewire proporciona una sintaxis simple pero extremadamente potente para controlar los indicadores de carga: wire:loading. Añadiendo wire:loading a cualquier elemento lo ocultará por defecto (usando display: none en CSS) y lo mostrará cuando se envíe una petición al servidor.

A continuación se muestra un ejemplo básico de un formulario del componente CreatePost con wire:loading que se utiliza para alternar un mensaje de carga:

<form wire:submit="guardar">
<!-- ... -->
<button type="submit">Guardar</button>
<div wire:loading>
Guardando Publicación...
</div>
</form>

Cuando un usuario pulsa “Guardar”, el mensaje “Guardando Publicación…” aparecerá debajo del botón mientras se ejecuta la acción de “guardar”. El mensaje desaparecerá cuando se reciba la respuesta del servidor y sea procesada por Livewire.

Quitar elementos

Alternativamente, puede añadir .remove para el efecto inverso, mostrando un elemento por defecto y ocultándolo durante las peticiones al servidor:

<div wire:loading.remove>...</div>

Cambio de clases

Además de cambiar la visibilidad de elementos enteros, a menudo resulta útil cambiar el estilo de un elemento existente activando y desactivando clases CSS durante las peticiones al servidor. Esta técnica puede utilizarse para cambiar los colores de fondo, reducir la opacidad, activar animaciones giratorias, etc.

A continuación se muestra un ejemplo sencillo del uso de la clase Tailwind opacity-50 para hacer que el botón “Guardar” sea más tenue mientras se envía el formulario:

<button wire:loading.class="opacity-50">Guardar</button>

Al igual que al alternar un elemento, puede realizar la operación inversa de la clase añadiendo .remove a la directiva wire:loading. En el ejemplo siguiente, la clase bg-blue-500 del botón se eliminará cuando se pulse el botón “Guardar”:

<button class="bg-blue-500" wire:loading.class.remove="bg-blue-500">
Guardar
</button>

Cambio de atributos

Por defecto, cuando se envía un formulario, Livewire desactiva automáticamente el botón de envío y añade el atributo readonly a cada elemento de entrada mientras se procesa el formulario.

Sin embargo, además de este comportamiento por defecto, Livewire ofrece el modificador .attr para permitirle alternar otros atributos en un elemento o alternar atributos en elementos que están fuera de los formularios:

<button
type="button"
wire:click="eliminacion"
wire:loading.attr="disabled"
>
Eliminar
</button>

Debido a que el botón de arriba no es un botón de envío, no será desactivado por el comportamiento por defecto de Livewire cuando se pulse. En su lugar, añadimos manualmente wire:loading.attr="disabled" para conseguir este comportamiento.

Acciones específicas

Por defecto, wire:loading se activará siempre que un componente realice una petición al servidor.

Sin embargo, en componentes con múltiples elementos que pueden lanzar peticiones al servidor, deberías delimitar tus indicadores de carga a acciones individuales.

Por ejemplo, considere el siguiente formulario “Guardar entrada”. Además de un botón “Guardar” que envía el formulario, también puede haber un botón “Eliminar” que ejecute una acción de “eliminación” en el componente.

Añadiendo wire:target al siguiente elemento wire:loading, puede indicar a Livewire que sólo muestre el mensaje de carga cuando se pulse el botón “Eliminar”:

<form wire:submit="guardar">
<!-- ... -->
<button type="submit">Guardar</button>
<button type="button" wire:click="eliminacion">Eliminar</button>
<div wire:loading wire:target="eliminacion">
Eliminando Publicación...
</div>
</form>

Al pulsar el botón “Eliminar”, se mostrará al usuario el mensaje “Eliminando Publicación…”. Sin embargo, el mensaje no se mostrará cuando se pulse el botón “Guardar”.

Dirigiéndose a múltiples acciones

Puede encontrarse en una situación en la que desee que wire:loading reaccione a algunas acciones de una página, pero no a todas. En estos casos puedes pasar múltiples acciones a wire:target separadas por una coma. Por ejemplo:

<form wire:submit="guardar">
<input type="text" wire:model.blur="title">
<!-- ... -->
<button type="submit">Guardar</button>
<button type="button" wire:click="eliminacion">Eliminar</button>
<div wire:loading wire:target="guardar, eliminacion">
Actualizando Publicacion...
</div>
</form>

El indicador de carga (“Actualizando Publicacion…”) ahora sólo se mostrará cuando se pulse el botón “Eliminar” o “Guardar”, y no cuando el campo $title se esté enviando al servidor.

Parámetros de acción Targeting

En situaciones en las que la misma acción se activa con diferentes parámetros desde varios lugares de una página, puede ampliar el alcance de wire:target a una acción específica pasando parámetros adicionales. Por ejemplo, considere el siguiente escenario en el que existe un botón “Eliminar” para cada entrada de la página:

<div>
@foreach ($posts as $post)
<div wire:key="{{ $post->id }}">
<h2>{{ $post->title }}</h2>
<button wire:click="eliminacion({{ $post->id }})">Eliminar</button>
<div wire:loading wire:target="eliminacion({{ $post->id }})">
Eliminando Publicación...
</div>
</div>
@endforeach
</div>

Sin pasar {{ $post->id }} a wire:target="eliminacion", el mensaje “Eliminando Publicación…” se mostraría al pulsar cualquiera de los botones de la página.

Sin embargo, como estamos pasando parámetros únicos a cada instancia de wire:target, Livewire sólo mostrará el mensaje de carga cuando se pasen los parámetros coincidentes a la acción “eliminacion”.

Orientación de actualizaciones de propiedades

Livewire también permite orientar actualizaciones de propiedades de componentes específicos pasando el nombre de la propiedad a la directiva wire:target.

Considere el siguiente ejemplo en el que una entrada de formulario llamada username utiliza wire:model.live para la validación en tiempo real a medida que el usuario escribe:

<form wire:submit="guardar">
<input type="text" wire:model.live="username">
@error('username') <span>{{ $message }}</span> @enderror
<div wire:loading wire:target="username">
Comprobación de la disponibilidad del nombre de usuario...
</div>
<!-- ... -->
</form>

El mensaje “Comprobando disponibilidad…” se mostrará cuando el servidor se actualice con el nuevo nombre de usuario cuando el usuario escriba en el campo de entrada.

Excluyendo objetivos de carga específicos

A veces puede desear mostrar un indicador de carga para cada petición Livewire excepto para una propiedad o acción específica. En estos casos puede utilizar el modificador wire:target.except de la siguiente manera:

<div wire:loading wire:target.except="descargar">...</div>

El indicador de carga anterior se mostrará ahora para cada solicitud de actualización de Livewire en el componente, excepto para la acción “descargar”.

Personalización de la propiedad CSS display

Cuando se añade wire:loading a un elemento, Livewire actualiza la propiedad CSS display del elemento para mostrar y ocultar el elemento. Por defecto, Livewire utiliza none para ocultar e inline-block para mostrar.

Si está alternando un elemento que utiliza un valor de visualización distinto de inline-block, como flex en el siguiente ejemplo, puede añadir .flex a wire:loading:

<div class="flex" wire:loading.flex>...</div>

A continuación se muestra la lista completa de valores de visualización disponibles:

<div wire:loading.inline-flex>...</div>
<div wire:loading.inline>...</div>
<div wire:loading.block>...</div>
<div wire:loading.table>...</div>
<div wire:loading.flex>...</div>
<div wire:loading.grid>...</div>

Retrasar un indicador de carga

En las conexiones rápidas, las actualizaciones suelen producirse tan rápidamente que los indicadores de carga sólo parpadean brevemente en la pantalla antes de desaparecer. En estos casos, el indicador es más una distracción que una ayuda.

Por esta razón, Livewire proporciona un modificador .delay para retrasar la aparición de un indicador. Por ejemplo, si añades wire:loading.delay a un elemento como este

<div wire:loading.delay>...</div>

El elemento anterior sólo aparecerá si la solicitud tarda más de 200 milisegundos. El usuario nunca verá el indicador si la petición se completa antes de ese tiempo.

Para personalizar la cantidad de tiempo para retrasar el indicador de carga, puede utilizar uno de los útiles alias de intervalo de Livewire:

<div wire:loading.delay.shortest>...</div> <!-- 50ms -->
<div wire:loading.delay.shorter>...</div> <!-- 100ms -->
<div wire:loading.delay.short>...</div> <!-- 150ms -->
<div wire:loading.delay>...</div> <!-- 200ms -->
<div wire:loading.delay.long>...</div> <!-- 300ms -->
<div wire:loading.delay.longer>...</div> <!-- 500ms -->
<div wire:loading.delay.longest>...</div> <!-- 1000ms -->