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:
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:
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:
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 // antesresources/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 adispatch()
(Del mismo modoemitTo()
yemitSelf()
son ahoradispatchTo()
ydispatchSelf()
)dispatchBrowserEvent()
ha pasado a llamarsedispatch()
- 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'); // AntesLivewire::test(Component::class)->assertDispatched('post-created'); // AHORA
Livewire::test(Component::class)->assertEmittedTo(Foo::class, 'post-created'); // AntesLivewire::test(Component::class)->assertDispatchedTo(Foo:class, 'post-created'); // AHORA
Livewire::test(Component::class)->assertNotEmitted('post-created'); // AntesLivewire::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', () => {...}) // Antesdocument.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
// AHORALivewire.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:
// AntesLivewire.hook("component.initialized", (component) => {});// AHORALivewire.hook("component.init", ({ component, cleanup }) => {});
// AntesLivewire.hook("element.initialized", (el, component) => {});// AHORALivewire.hook("element.init", ({ el, component }) => {});
// AntesLivewire.hook("element.updating", (fromEl, toEl, component) => {});// AHORALivewire.hook("morph.updating", ({ el, toEl, component }) => {});
// AntesLivewire.hook("element.updated", (el, component) => {});// AHORALivewire.hook("morph.updated", ({ el, component }) => {});
// AntesLivewire.hook("element.removed", (el, component) => {});// AHORALivewire.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.