Laravel Livewire: 14 consejos y trucos


Victor Arana Flores

15 Aug 2022

Laravel Livewire es una gran herramienta para conseguir un comportamiento dinámico en la página, sin necesidad de escribir directamente código JavaScript. Y, como toda herramienta, tiene un montón de "joyas ocultas", tanto en su documentación oficial, como en consejos prácticos extra proporcionados por los desarrolladores. He decidido recopilar algunos de ellos en este artículo. ¡Entremos en materia!

1. No se necesita render()

Un método típico de render() se parece a esto:

// app/Http/Livewire/PostsShow.php
class PostsShow extends Component
{
    public function render()
    {
        return view('livewire.posts-show');
    }
}

Pero si su método render() es sólo una línea para renderizar la vista por defecto, puede eliminar ese método render() del componente y todo seguirá funcionando, cargando el render() por defecto del método del proveedor.

class PostsShow extends Component
{
    // Este componente vacío seguirá funcionando y cargará el archivo Blade
}

2. Componentes en subcarpetas

Si quieres generar un componente en una subcarpeta, como app/Http/Livewire/Folder/Component.php, tienes dos formas de hacerlo:

php artisan make:livewire Folder/Component

o

php artisan make:livewire folder.component

Observe que la primera forma es con la primera letra en mayúscula, y la segunda forma es en minúscula. En ambos casos, habrá dos archivos generados:

  • app/Http/Livewire/Carpeta/Componente.php
  • resources/views/livewire/folder/component.blade.php

Las subcarpetas se crearán automáticamente si no existen.

3. Componentes en carpeta no predeterminada

Si utiliza algún paquete externo con componentes Livewire, puede tener su componente Livewire en una carpeta diferente a la predeterminada app/Http/Livewire. Entonces, es posible que tenga que vincular su nombre a la ubicación real.

Normalmente, se hace en app/Providers/AppServiceProvider.php (o en cualquier proveedor de servicios) método boot():

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Livewire::component('shopping-cart', \Modules\Shop\Http\Livewire\Cart::class);
    }
}

4. Cambiar el nombre o mover los componentes fácilmente

Si has cometido un error al generar el componente con make:livewire, no te preocupes. No necesitas renombrar dos archivos manualmente, hay un comando para eso.

Por ejemplo, si escribiste php artisan make:livewire Prduct, pero en su lugar quieres "Product", y también decidiste ponerlo en una subcarpeta, puedes seguir con este comando:

php artisan livewire:move Prduct Products/Show

El resultado será este:

COMPONENT MOVED
CLASS: app/Http/Livewire/Prduct.php
    => app/Http/Livewire/Products/Show.php
VIEW:  resources/views/livewire/prduct.blade.php
    => resources/views/livewire/products/show.blade.php

5. Cambiar las plantillas de componentes por defecto

Los componentes de Livewire se generan utilizando las plantillas por defecto, llamadas "stubs". Están escondidos en la carpeta "vendor" del paquete Livewire, pero puede publicarlos y editarlos según sus necesidades.

Ejecute este comando:

php artisan livewire:stubs

Encontrará una nueva carpeta /stubs con algunos archivos.

Ejemplo de un stubs/livewire.stub:

<?php
 
namespace [namespace];
 
use Livewire\Component;
 
class [class] extends Component
{
    public function render()
    {
        return view('[view]');
    }
}

Por ejemplo, si quieres generar los componentes sin el método render(), simplemente elimínalo del archivo stub, y entonces cada vez que ejecutes php artisan make:livewire Component, tomará la plantilla de tu stub público actualizado.

6. No cree un método sólo para establecer un valor

Si tienes un evento de clic que establezca algún valor de alguna propiedad, puedes hacer algo así:

<button wire:click="showText">Show</button>

Y luego

class Show extends Component
{
    public $showText = false;
 
    public function showText() {
        $this->showText = true;
    }
}

Pero en realidad, puede asignar un nuevo valor a la propiedad Livewire directamente desde su archivo Blade, sin tener un método separado en el componente Livewire.

Aquí está el código:

<button wire:click="$set('showText', true)">Show</button>

Por lo tanto, usted llama a $set y proporciona dos parámetros: el nombre de su propiedad y el nuevo valor

7. Vaya aún más lejos: Establezca fácilmente el valor verdadero/falso

Siguiendo con el último consejo, si tu propiedad es una variable booleana con valores verdadero/falso, y quieres tener un botón de mostrar/ocultar, puedes hacer algo así:

<button wire:click="$toggle('showText')">Show/Hide</button>

Aviso: Personalmente evitaría usar Livewire para tales efectos simples de alternancia porque añade la petición adicional al servidor.

En su lugar, es mejor utilizar JavaScript para esto, como Alpine.js:

<div x-data="{ open: false }">
    <button @click="open = true">Expand</button>
 
    <span x-show="open">
      Content...
    </span>
</div>

8. Tres formas de minimizar las peticiones al servidor

Una de las principales críticas a Livewire es el hecho de que hace demasiadas peticiones al servidor. Si tiene wire:model en el campo de entrada, cada pulsación de tecla podría llamar al servidor para volver a renderizar el componente. Es muy conveniente si tienes algunos efectos en tiempo real, como la "búsqueda en vivo". Pero generalmente, las peticiones al servidor pueden ser bastante caras, en términos de rendimiento.

Sin embargo, es muy fácil personalizar este comportamiento de wire:model.

  1. wire:model.debounce: por defecto, Livewire espera 150ms después de la pulsación en la entrada, antes de realizar la petición al servidor. Pero puedes anularlo: <input type="text" wire:model.debounce.1000ms="propertyName">
  2. wire:model.lazy: por defecto, Livewire está a la escucha de todos los eventos de la entrada, y entonces realiza las peticiones al servidor. Al proporcionar una directiva lazy, le dices a Livewire que escuche sólo el evento change. Esto significa que el usuario puede seguir escribiendo y cambiando el valor, y la petición al servidor se disparará sólo cuando el usuario haga clic fuera de ese campo.
  3. wire:model.defer: esto no disparará las peticiones del servidor al cambiar la entrada. Guardará el nuevo valor internamente y lo pasará a la siguiente petición de red, que puede provenir de otros campos de entrada u otros clics de botón.

9. Personalizar los atributos de validación

La validación de Livewire funciona de forma muy similar al motor de validación de Laravel, pero con algunas diferencias. En Laravel, si quieres personalizar los nombres de los atributos, puedes definir el método attributes() en una clase Form Request.

class ContactForm extends Component
{
    protected $validationAttributes = [
        'email' => 'email address'
    ];
 
    // ...

Esto es útil para los mensajes de error comunes, como "El campo [XYZ] es necesario". Por defecto, ese XYZ se sustituye por el nombre del campo, que puede no ser una palabra amigable para los humanos, por lo que vale la pena sustituirlo para los mensajes de error por algo más claro.

10. Indicadores de carga

Algo que está descrito en la documentación oficial pero que se usa bastante poco, por lo que he visto. Si alguna acción tarda en aparecer en pantalla, vale la pena mostrar algún indicador de carga, como un gif girando, o simplemente un texto de "Cargando datos..."

En Livewire, es muy fácil no sólo de implementar sino también de personalizar.

El ejemplo más sencillo de procesamiento de datos: cuando se realiza la petición al servidor, se mostrará el texto "Procesando pago..." hasta que se termine la petición al servidor y vuelva con el resultado.

<div>
    <button wire:click="checkout">Checkout</button>
 
    <div wire:loading>
        Procesar el pago...
    </div>
</div>

En la práctica, me gusta mostrar estos indicadores de carga sólo si tardan un poco. No tiene sentido volver a renderizar el DOM cada vez, en todos los casos posibles. ¿Y si lo hacemos sólo si la petición tarda más de 500ms?

Fácil:

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

También hay posibilidades de jugar con las clases CSS para cargar los estados, adjuntarlos a acciones específicas, y más: lee en la documentación oficial.

11. Indicador de desconexión

Otra característica documentada pero menos conocida de Livewire es la de indicar al usuario si su conexión a Internet se ha perdido. Puede ser beneficioso si su aplicación trabaja con datos en tiempo real o con múltiples actualizaciones en la pantalla: puede difuminar algunas partes de la página web y mostrar el texto "offline".

Es tan fácil como esto:

<div wire:offline>
    Ahora está desconectado.
</div>

También, como he mencionado, puedes difuminar algunos elementos, asignando clases CSS, así:

<div wire:offline.class="bg-red-300"></div>

12. Paginación con Bootstrap Framework

Al igual que Laravel, Livewire utiliza por defecto el estilo de paginación del framework Tailwind. Por suerte, es fácil de anular, sólo tiene que proporcionar el valor diferente a la propiedad:

class ShowPosts extends Component
{
    use WithPagination;
 
    protected $paginationTheme = 'bootstrap';

Puedes consultar los diseños de paginación disponibles directamente en el repositorio Github de Livewire. Navegando por ahí, no he encontrado ninguna información sobre si se utiliza la versión Bootstrap 4 o Bootstrap 5.

13. Sin mount: Automatic Route-Model Binding

Si quieres pasar un objeto al componente Livewire, esta es la forma típica de hacerlo, con el método mount():

class ShowPost extends Component
{
    public $post;
 
    public function mount(Post $post)
    {
        $this->post = $post;
    }
}

Entonces, en algún lugar de Blade, tienes @livewire('show-post', $post).

Pero, ¿sabías que si proporcionas una sugerencia de tipo a la propiedad Livewire, esa vinculación ruta-modelo ocurriría automáticamente?

class ShowPost extends Component
{
    public Post $post;
}

Eso es todo, no es necesario tener el método mount() en absoluto.

14. Modal para confirmar eliminación

Si tienes un botón "Eliminar" y quieres llamar al modal JavaScript de confirmación antes de realizar la acción, este código no funcionaría correctamente en Livewire:

<button wire:click="delete($post->id)"
        onclick="return confirm('¿Está seguro?')">Borrar</button>

Hay algunas soluciones posibles para esto, probablemente la más elegante es detener el evento Livewire antes de que ocurra:

<button onclick="confirm('¿Está seguro?') || event.stopImmediatePropagation()"
        wire:click="delete($post->id)">Borrar</button>

Ese event.stopImmediatePropagation() hará que el método Livewire deje de ser llamado, si el resultado de la confirmación es falso.

Puedes encontrar otras posibles soluciones en esta discusión de Github.


Eso es todo, características menos conocidas de Livewire y pequeños consejos. ¡Espero que haya sido útil!

Articulo traducido del blog de Laravel New


6 comentarios

Inicia sesión para comentar

Comentarios:

  • Luis Nieto

    Luis Nieto hace 1 año

    Excelente amigo Victor

  • Antonio Lanas

    Antonio Lanas hace 1 año

    Estupendo

  • Cesar Valero

    Cesar Valero hace 1 año

    Marginifo aporte

     

    • Victor Arana Flores hace 1 año

      Gracias Cesar

  • Fatima Chamo

    Fatima Chamo hace 1 año

    Estoy haciendo el crud en livewire y usando adminlte3 instalo por composer, cuando agrego el buton de crear un nuevo Post no me carga ni genera los colores.
    Alguna sugerencia?

  • Marcos Socrates Suyo Mendoza

    Marcos Socrates Suyo Mendoza hace 1 año

    El 14 no me lo sabía, es bueno saber :D

  • Walter Ramos

    Walter Ramos hace 1 año

    Buen articulo! Habia cosas que no sabia y esta bueno saberlas.