Saltearse al contenido

Guía de actualización

Para ahorrarte tiempo actualizando, hemos incluido un comando Artisan para automatizar tantas partes del proceso de actualización como sea posible.

Después de instalar la versión 3 de Livewire, ejecute el siguiente comando, y recibirá avisos para actualizar cada cambio de última hora automáticamente:

Ventana de terminal
php artisan livewire:upgrade

Aunque el comando anterior puede actualizar gran parte de tu aplicación, la única forma de garantizar una actualización completa es seguir la guía paso a paso de esta página.

Actualizar PHP

Livewire ahora requiere que su aplicación se ejecute en PHP versión 8.1 o superior.

Actualizar Livewire a la versión 3

Ejecute el siguiente comando composer para actualizar la dependencia Livewire de su aplicación de la versión 2 a la 3:

Ventana de terminal
composer require livewire/livewire "^3.0"

Compatibilidad con el paquete Livewire 3

La mayoría de los paquetes Livewire de terceros soportan actualmente Livewire 3 o están trabajando para soportarlo pronto. Sin embargo, es inevitable que haya paquetes que tarden más tiempo en ofrecer soporte para Livewire 3.

Borrar la caché de vistas

Ejecute el siguiente comando Artisan desde el directorio raíz de su aplicación para borrar cualquier vista Blade cacheada/compilada y forzar a Livewire a re-compilarlas para que sean compatibles con Livewire 3:

Ventana de terminal
php artisan view:clear

Mergear nueva configuración

Livewire 3 ha cambiado múltiples opciones de configuración. Si su aplicación tiene un archivo de configuración publicado (config/livewire.php), deberá actualizarlo para tener en cuenta los siguientes cambios.

Nueva configuración

Las siguientes claves de configuración han sido introducidas en la versión 3:

'legacy_model_binding' => false,
'inject_assets' => true,
'inject_morph_markers' => true,
'navigate' => false,
'pagination_theme' => 'tailwind',

Puede consultar el nuevo archivo de configuración de Livewire en GitHub para obtener descripciones adicionales de las opciones y código copiable.

Configuración modificada

Se han actualizado los siguientes elementos de configuración con nuevos valores por defecto:

Nuevo Namespaces de clase

El class_namespace por defecto de Livewire ha cambiado de App\Http\Livewire a App\Livewire. Puede mantener el antiguo valor de configuración del Namespace; sin embargo, si decide actualizar su configuración al nuevo Namespaces, tendrá que mover sus componentes Livewire a app/Livewire:

'class_namespace' => 'App\\Http\\Livewire', // Antes
'class_namespace' => 'App\\Livewire', // Ahora

Nueva ruta de vista de diseño

Al renderizar componentes de página completa en la versión 2, Livewire utilizaba resources/views/layouts/app.blade.php como componente Blade de diseño por defecto.

Debido a la creciente preferencia de la comunidad por componentes Blade anónimos, Livewire 3 ha cambiado la ubicación por defecto a: resources/views/components/layouts/app.blade.php.

'layout' => 'layouts.app', , // Antes
'layout' => 'components.layouts.app', // Ahora

Configuración eliminada

app_url

Si tu aplicación se sirve bajo una URI no raíz, en Livewire 2 podías usar la opción de configuración app_url para configurar la URL que Livewire usa para hacer peticiones AJAX a.

En este caso, hemos encontrado que una configuración de cadena es demasiado rígida. Por lo tanto, Livewire 3 ha optado por utilizar la configuración en tiempo de ejecución en su lugar. Puede consultar nuestra documentación sobre la configuración del endpoint de actualización de Livewire para más información.

asset_url

En Livewire 2, si su aplicación se servía bajo una URI no raíz, usaría la opción de configuración asset_url para configurar la URL base que Livewire usa para servir sus assets JavaScript.

Livewire 3 ha optado por una estrategia de configuración en tiempo de ejecución. Puede consultar nuestra documentación sobre la configuración del endpoint de assets de script de Livewire para obtener más información.

middleware_group

Dado que Livewire expone ahora una forma más flexible de personalizar su endpoint de actualización, se ha eliminado la opción de configuración middleware_group.

Puede consultar nuestra documentación sobre la personalización del endpoint de actualización de Livewire para obtener más información sobre la aplicación de middleware personalizado a las solicitudes de Livewire.

manifest_path

Livewire 3 ya no utiliza un archivo de manifiesto para la autocarga de componentes. Por lo tanto, la configuración manifest_path ya no es necesaria.

back_button_cache

Dado que Livewire 3 ofrece ahora una experiencia SPA para su aplicación utilizando wire:navigate, la configuración back_button_cache ya no es necesaria.

Namespace de la aplicación Livewire

En la versión 2, los componentes Livewire se generaban y reconocían automáticamente bajo el espacio de nombres App\Http\Livewire.

Livewire 3 ha cambiado este valor por defecto a: App\Livewire.

Puede mover todos sus componentes a la nueva ubicación o añadir la siguiente configuración al archivo de configuración config/livewire.php de su aplicación:

'class_namespace' => 'App\\Http\\Livewire',

Descubriendo Componentes

Con Livewire 3, no hay manifiesto presente, y por lo tanto no hay nada que «descubrir» en relación con Livewire Components, y puede eliminar con seguridad cualquier referencia livewire:discover de sus scripts de compilación sin problemas.

Vista de los componentes

Al renderizar componentes Livewire como páginas completas utilizando una sintaxis como la siguiente:

Route::get('/posts', ShowPosts::class);

El archivo de diseño Blade utilizado por Livewire para renderizar el componente ha cambiado de resources/views/layouts/app.blade.php a resources/views/components/layouts/app.blade.php:

resources/views/layouts/app.blade.php // antes
resources/views/components/layouts/app.blade.php // ahora

Puedes mover tu archivo de layout a la nueva ubicación o aplicar la siguiente configuración dentro del archivo de configuración config/livewire.php de tu aplicación:

'layout' => 'layouts.app',

Para obtener más información, consulte la documentación sobre la creación y el uso de un diseño de componente de página.

Vinculación (Binding) de modelos Eloquent

Livewire 2 soportaba el enlace wire:model directamente a las propiedades del modelo Eloquent. Por ejemplo, lo siguiente era un patrón común:

public Post $post;
protected $rules = [
'post.title' => 'required',
'post.description' => 'required',
];
<input wire:model="post.title" />
<input wire:model="post.description" />

En Livewire 3, la vinculación directa (Binding) a modelos Eloquent se ha deshabilitado en favor del uso de propiedades individuales, o la extracción de Objetos de Formulario.

Sin embargo, debido a que este comportamiento es muy utilizado en las aplicaciones Livewire, la versión 3 mantiene el soporte para este comportamiento a través de un elemento de configuración en config/livewire.php:

'legacy_model_binding' => true,

Estableciendo legacy_model_binding a true, Livewire manejará las propiedades del modelo Eloquent exactamente como lo hacía en la versión 2.

AlpineJS

Livewire 3 viene con AlpineJS por defecto.

Si incluye Alpine manualmente en su aplicación Livewire, deberá eliminarlo para que la versión incorporada de Livewire no entre en conflicto.

Incluyendo Alpine a través de una etiqueta script

Si incluye Alpine en su aplicación a través de una etiqueta de script como la siguiente, puede eliminarla completamente y Livewire cargará su versión interna en su lugar:

<script
defer
src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"
></script>

Incluyendo plugins mediante una etiqueta de script

Livewire 3 incluye ahora los siguientes plugins Alpine:

Vale la pena estar atento a los cambios en el archivo package.json, ¡ya que pueden añadirse nuevos plugins de Alpine!

Si previamente ha incluido alguno de estos en su aplicación a través de etiquetas <script> como las de abajo, debe eliminarlos junto con el núcleo de Alpine:

<!-- Eliminar -->
<script
defer
src="https://cdn.jsdelivr.net/npm/@alpinejs/intersect@3.x.x/dist/cdn.min.js"
></script>
<!-- ... -->

Acceso a Alpine global a través de una etiqueta script

Si actualmente está accediendo al objeto global Alpine desde una etiqueta script como esta:

<script>
document.addEventListener('alpine:init', () => {
Alpine.data(...)
})
</script>

Puedes seguir haciéndolo, ya que Livewire incluye y registra internamente el objeto global de Alpine como antes.

Incluyendo vía paquete de JS

Si ha incluido Alpine o cualquiera de los populares plugins del núcleo de Alpine mencionados anteriormente a través de NPM en el paquete JavaScript de sus aplicaciones de esta manera:

// Advertencia: esto es un fragmento de como se hacía en Livewire 2 para incluir Alpine
import Alpine from "alpinejs";
import intersect from "@alpinejs/intersect";
Alpine.plugin(intersect);
Alpine.start();

Puede eliminarlos por completo, ya que Livewire incluye Alpine y muchos plugins populares de Alpine por defecto.

Acceso a Alpine a través del paquete JS

Si está registrando plugins o componentes personalizados de Alpine dentro del bundle JavaScript de su aplicación de esta forma:

// Advertencia: esto es un fragmento de como se hacía en Livewire 2 para incluir Alpine
import Alpine from "alpinejs";
import customPlugin from "./plugins/custom-plugin";
Alpine.plugin(customPlugin);
Alpine.start();

Todavía puede lograr esto importando el módulo ESM del núcleo de Livewire en su paquete y accediendo a Alpine desde allí.

Para importar Livewire a su paquete, primero debe desactivar la inyección normal de JavaScript de Livewire y proporcionar la configuración necesaria a Livewire sustituyendo @livewireScripts por @livewireScriptConfig en el diseño principal de su aplicación:

<!-- ... -->
@livewireScripts // Borramos
@livewireScriptConfig // Añadimos
</body>

Ahora, puede importar Alpine y Livewire en el paquete de su aplicación de la siguiente manera:

import {
Livewire,
Alpine,
} from "../../vendor/livewire/livewire/dist/livewire.esm";
import customPlugin from "./plugins/custom-plugin";
Alpine.plugin(customPlugin);
Livewire.start();

Note que ya no necesita llamar a Alpine.start(). Livewire iniciará Alpine automáticamente.

Para más información, por favor consulte nuestra documentación sobre cómo empaquetar manualmente el JavaScript de Livewire.

wire:model

En Livewire 3, wire:model es «diferido» por defecto (en lugar de por wire:model.defer). Para conseguir el mismo comportamiento que wire:model de Livewire 2, debes usar wire:model.live.

A continuación hay una lista de las sustituciones necesarias que tendrás que hacer en tus plantillas para mantener el comportamiento de tu aplicación consistente:

<input wire:model="..."> // Antes
<input wire:model.live="..."> // AHORA
<input wire:model.defer="..."> // Antes
<input wire:model="..."> // AHORA
<input wire:model.lazy="..."> // Antes
<input wire:model.blur="..."> // AHORA

@entangle

De forma similar a los cambios en wire:model, Livewire 3 aplaza todos los enlaces de datos por defecto. Para adaptarse a este comportamiento, @entangle también se ha actualizado.

Para mantener su aplicación funcionando como se espera, haga las siguientes sustituciones @entangle:

@entangle(...) // Antes
@entangle(...).live // AHORA
@entangle(...).defer // Antes
@entangle(...) // AHORA

Eventos (events)

En Livewire 2, Livewire tenía dos métodos PHP diferentes para disparar eventos:

  • emit()
  • dispatchBrowserEvent()

Livewire 3 ha unificado estos dos métodos en uno solo:

  • dispatch()

He aquí un ejemplo básico de envío y escucha de un evento en Livewire 3:

// Envío... (Dispatching....)
class CreatePost extends Component
{
public Post $post;
public function save()
{
$this->dispatch('post-created', postId: $this->post->id);
}
}
// Escuchando... (Listening...)
class Dashboard extends Component
{
#[On('post-created')]
public function postAdded($postId)
{
//
}
}

Los tres cambios principales de Livewire 2 son:

  • emit() ha sido renombrada a dispatch() (Del mismo modo emitTo() y emitSelf() son ahora dispatchTo() y dispatchSelf())
  • dispatchBrowserEvent() ha pasado a llamarse dispatch()
  • Todos los parámetros de evento deben ser llamados

Para más información, consulte la nueva página de documentación sobre eventos.

Estas son las diferencias de «buscar y reemplazar» que deben aplicarse a su aplicación:

$this->emit('post-created'); // Antes
$this->dispatch('post-created'); // AHORA
$this->emitTo('foo', 'post-created'); // Antes
$this->dispatch('post-created')->to('foo'); // AHORA
$this->emitSelf('post-created'); // Antes
$this->dispatch('post-created')->self(); // AHORA
$this->emit('post-created', $post->id); // Antes
$this->dispatch('post-created', postId: $post->id); // AHORA
$this->dispatchBrowserEvent('post-created'); // Antes
$this->dispatch('post-created'); // AHORA
$this->dispatchBrowserEvent('post-created', ['postId' => $post->id]); // Antes
$this->dispatch('post-created', postId: $post->id); // AHORA
<!-- Antes -->
<button wire:click="$emit('post-created')">...</button>
<!-- AHORA -->
<button wire:click="$dispatch('post-created')">...</button>
<!-- Antes -->
<button wire:click="$emit('post-created', 1)">...</button>
<!-- AHORA -->
<button wire:click="$dispatch('post-created', { postId: 1 })">...</button>
<!-- Antes -->
<button wire:click="$emitTo('foo', post-created', 1)">...</button>
<!-- AHORA -->
<button wire:click="$dispatchTo('foo', 'post-created', { postId: 1 })">
...
</button>
<!-- Antes -->
<button x-on:click="$wire.emit('post-created', 1)">...</button>
<!-- AHORA -->
<button x-on:click="$dispatch('post-created', { postId: 1 })">...</button>

emitUp()

El concepto de emitUp se ha eliminado por completo. Ahora los eventos se envían utilizando eventos del navegador y, por lo tanto, «burbujearán» por defecto.

Puede eliminar cualquier instancia de $this->emitUp(...) o $emitUp(...) de sus componentes.

Pruebas de eventos

Livewire también ha cambiado las aserciones de eventos para adaptarlas a la nueva terminología unificada sobre el envío de eventos:

Livewire::test(Component::class)->assertEmitted('post-created'); // Antes
Livewire::test(Component::class)->assertDispatched('post-created'); // AHORA
Livewire::test(Component::class)->assertEmittedTo(Foo::class, 'post-created'); // Antes
Livewire::test(Component::class)->assertDispatchedTo(Foo:class, 'post-created'); // AHORA
Livewire::test(Component::class)->assertNotEmitted('post-created'); // Antes
Livewire::test(Component::class)->assertNotDispatched('post-created'); // AHORA
Livewire::test(Component::class)->assertEmittedUp() // Antes

URL query string

En versiones anteriores de Livewire, si vinculaba una propiedad a la cadena de consulta de la URL, el valor de la propiedad siempre estaría presente en la cadena de consulta, a menos que utilizara la opción except.

En Livewire 3, todas las propiedades vinculadas a la cadena de consulta sólo se mostrarán si su valor ha sido cambiado después de la carga de la página. Esta opción por defecto elimina la necesidad de la opción except:

public $search = '';
protected $queryString = [
'search' => ['except' => ''], // Antes
'search', // AHORA
];

Si desea volver al comportamiento de Livewire 2 de mostrar siempre una propiedad en la cadena de consulta sin importar su valor, puede utilizar la opción mantener:

public $search = '';
protected $queryString = [
'search' => ['keep' => true],
];

Paginación

El sistema de paginación ha sido actualizado en Livewire 3 para soportar mejor múltiples paginadores dentro del mismo componente.

Actualizar las vistas de paginación publicadas

Si has publicado las vistas de paginación de Livewire, puedes hacer referencia a las nuevas en el directorio de paginación en GitHub y actualizar tu aplicación en consecuencia.

Acceso directo a $this->page

Dado que Livewire soporta ahora múltiples paginadores por componente, ha eliminado la propiedad $page de la clase componente y la ha sustituido por una propiedad $paginators que almacena un array de paginadores:

$this->page = 2; // Antes
$this->paginators['page'] = 2; // AHORA

Sin embargo, se recomienda utilizar los métodos getPage y setPage proporcionados para modificar y acceder a la página actual:

// Obtener Página
$this->getPage();
// Seleccionar Página
$this->setPage(2);

wire:click.prefetch

La función de precarga de Livewire (wire:click.prefetch) ha sido eliminada por completo. Si usted dependía de esta función, su aplicación seguirá funcionando, sólo será un poco menos eficiente en los casos en los que anteriormente se beneficiaba de .prefetch.

<button wire:click.prefetch=""> // Antes
<button wire:click="..."> // Ahora

Cambios en la clase Component

Se han realizado los siguientes cambios en la clase base Livewire\Component de Livewire en la que pueden haber confiado los componentes de su aplicación.

La propiedad $id del componente

Si accedía al ID del componente directamente a través de $this->id, debe utilizar en su lugar $this->getId():

$this->id; // Antes
$this->getId(); // Ahora

Duplicar nombres de métodos y propiedades

PHP le permite usar el mismo nombre tanto para una propiedad de clase como para un método. En Livewire 3, esto causará problemas al llamar a métodos desde el frontend vía wire:click.

Se recomienda encarecidamente utilizar nombres distintos para todos los métodos públicos y propiedades de un componente:

public $search = ''; // Antes
public function search() {
// ...
}
public $query = ''; // Ahora
public function search() {
// ...
}

Vambios en la API de Javascript

livewire:load

En versiones anteriores de Livewire, podías escuchar el evento livewire:load para ejecutar código JavaScript inmediatamente antes de que Livewire inicializara la página.

En Livewire 3, el nombre del evento ha cambiado a livewire:init para coincidir con alpine:init de Alpine:

document.addEventListener('livewire:load', () => {...}) // Antes
document.addEventListener('livewire:init', () => {...}) // AHORA

Hook de Página Expirada

En la versión 2, Livewire expuso un método JavaScript dedicado para personalizar el comportamiento de expiración de la página: Livewire.onPageExpired(). Este método se ha eliminado en favor del uso directo de los Hooks de solicitudes más potentes:

Livewire.onPageExpired(() => {...}) // Antes
// AHORA
Livewire.hook('request', ({ fail }) => {
fail(({ status, preventDefault }) => {
if (status === 419) {
preventDefault()
confirm('Your custom page expiration behavior...')
}
})
})

Nuevos Hooks de ciclo de vida Muchos de los Hooks internos de JavaScript del ciclo de vida de Livewire han cambiado en Livewire 3.

Aquí tienes una comparación de los antiguos hooks y sus nuevas sintaxis para que los encuentres/reemplaces en tu aplicación:

// Antes
Livewire.hook("component.initialized", (component) => {});
// AHORA
Livewire.hook("component.init", ({ component, cleanup }) => {});
// Antes
Livewire.hook("element.initialized", (el, component) => {});
// AHORA
Livewire.hook("element.init", ({ el, component }) => {});
// Antes
Livewire.hook("element.updating", (fromEl, toEl, component) => {});
// AHORA
Livewire.hook("morph.updating", ({ el, toEl, component }) => {});
// Antes
Livewire.hook("element.updated", (el, component) => {});
// AHORA
Livewire.hook("morph.updated", ({ el, component }) => {});
// Antes
Livewire.hook("element.removed", (el, component) => {});
// AHORA
Livewire.hook("morph.removed", ({ el, component }) => {});
// Eliminados:
Livewire.hook("message.sent", (message, component) => {});
Livewire.hook("message.failed", (message, component) => {});
Livewire.hook("message.received", (message, component) => {});
Livewire.hook("message.processed", (message, component) => {});
// Implementado:
Livewire.hook("commit", ({ component, commit, respond, succeed, fail }) => {
// Equivalent of 'message.sent'
succeed(({ snapshot, effect }) => {
// Equivalent of 'message.received'
queueMicrotask(() => {
// Equivalent of 'message.processed'
});
});
fail(() => {
// Equivalent of 'message.failed'
});
});

Puede consultar la nueva documentación sobre Hooks de JavaScript para comprender mejor el nuevo sistema de ganchos.

Localización

Si su aplicación utiliza un prefijo de localización en la URI como https://example.com/en/..., Livewire 2 conservaba automáticamente este prefijo de URL al realizar actualizaciones de componentes a través de https://example.com/en/livewire/update.

Livewire 3 ha dejado de soportar este comportamiento automáticamente. En su lugar, puedes sobreescribir el punto final de actualización de Livewire con cualquier prefijo URI que necesites usando setUpdateRoute():

Route::group(['prefix' => LaravelLocalization::setLocale()], function ()
{
// Sus otras rutas localizadas...
Livewire::setUpdateRoute(function ($handle) {
return Route::post('/livewire/update', $handle);
});
});

Para más información, consulte nuestra documentación sobre la configuración del endpoint de actualización de Livewire.