LIVEWERE
LIVEWERE
LIVEWERE
También se puede pasar el nombre de una carpeta donde deberá generarse dicho componente, por
ejemplo
Afectará a la ruta del archivo blade creado como del archivo php
app/Http/Livewire/Carpeta/nombreDelComponente.php
resources/views/livewire/Carpeta/nombre-del-componente.blade.php
app/Http/Livewire
y el segundo en
resources/views/livewire
app/Http/Livewire/nombreDelComponente.php
resources/views/livewire/nombreDelComponente.blade.php
El archivo .php contiene la lógica y el método Render del componente, mientras que el archivo blade
contiene la vista
El archivo php
- Cada que cambia algo en la interfaz el metodo render comprobara cambios y mostrara segun sea
necesario
- Al recibir datos desde blade se debe definir una propiedad pública para dicho valor, en este ejemplo
public $title[1]
- El metodo mount permite recibir los valores desde blade y trabajar con ellos permitiendo reasignar [1]
por ejemplo
public $titulo;
-El archivo php controlador puede ser usado de forma directa en una ruta, esto en caso de que se requiera el
archivo blade sea lo unico
que se muestra, por ejemplo
use App\Http\Livewire\ShowPosts; <-- Controlador del componente
Esto renderizara la vista del componente usando el slot(el que no tiene nombre $slot) dentro del archivo
resources/views/layouts/app.blade
por defecto en caso de requerir usar un layout distinto a este se debe usar la funcion layout dentro de render, y
especificar
la ruta de dicho archivo(considerando que leera desde views), se pueden usar otros slots con nombre dentro de
dicha vista del componente
Se pueden usa
El archivo blade
- Este debe ser siempre contenido dentro de dos etiquetas de inicio y de cierre normalmente un div
- Para traer un componente dentro de un archivo blade se debe usar la directiva de blade @livewire('nombre-
del-componente')
- Para enviar datos a un componente que se usa como controlador y uno archivo en una vista
Route::get('prueba/{name}',ShowPosts::class);
public $name;
public function mount($name){
$this->name = $name;
}
En este caso los elementos th tienen asignado una accion click la cual llama a una función llamada order que
recibe un parametro
En el controlador de dicho componente se define la funcion order y se prepara para recibir los parametros
En este caso ya que sort es una variable que depende de la interacción del usuario se escribe código dentro del
archivo blade que
se renderizara según el valor de sort
@else
<i class="fas fa-sort float-right mt-1"></i>
@endif
mix.js('resources/js/app.js', 'public/js')
.postCss('resources/css/app.css', 'public/css', [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer'),
])
.sass('resources/sass/app.scss', 'public/css');
if (mix.inProduction()) {
mix.version();
}
2.- Go ahead and install fontawesome:
@import '~@fortawesome/fontawesome-free/scss/fontawesome';
@import '~@fortawesome/fontawesome-free/scss/regular';
@import '~@fortawesome/fontawesome-free/scss/solid';
@import '~@fortawesome/fontawesome-free/scss/brands';
4.- Execute the following commands:
Los métodos mágicos sirven para modificar el valor de una variable de forma rapida, esto ayuda a reducir
código en el controlador
del componente
<x-jet-secondary-button wire:click="$set('open',false)">
Cancelar
</x-jet-secondary-button>
<x-jet-danger-button wire:click="$set('open',true)">
Crear nuevo post
</x-jet-danger-button>
En este caso el componente secondary button asigna el valor false a la variable open del componente, mientras
que el danger button
asigna el valor true
Se usa para evitar que livewire envie peticiones para actualizar cambios de un valor del controlador del
componente por ejemplo
<x-jet-danger-button wire:click="save">
Crear post
</x-jet-danger-button>
El componente input tiene asignado el valor title pero no enviara el valor al controlador del componente hasta
que otra acción
dentro de la vista componente sea llamada en este caso el componente danger button que llama a la acción
save, esto con la
intención de no hacer peticiones innecesarias al servidor ya que la intención guardar mas no mostrar en vivo los
cambios
Dentro de la carpeta resources/css/ se pueden crear diferentes archivos para ser usados como estilos, en este
caso en concreto se crea el
archivo form.css donde se añaden las siguientes lineas
.form-control{
@apply border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50
rounded-md shadow-sm
}
Esto para despues incluir dicho archivo en app.css usando las siguientes lineas
@import 'form.css';
para que se reflejen los archivos dentro de el mix se debe utilizar el comando
Para comunicar componentes se debe usar los metodos emit y la propiedad listener
donde
Tambien se puede emitir un evento sin definir oyentes o parametros, todos los componentes involucrados en el
mismo blade
escucharan este evento(siempre que esten listos para escuchar el evento)
$this->emit('render');
Para escuchar eventos dentro de un controlador de un componente se debe usar la propiedad listeners que es
un arreglo
Esto escuchara el evento render y procedera a ejecutar la función render, en caso de que el evento que
escucha y el nombre de la función
que se pretende ejecutar tengan el mismo nombre se puede omitir definir el nombre de la función es decir
<script>
Livewire.on('alert',(message)=>{
Swal.fire(
'Good job!',
message,
'success'
)
});
</script>
En este caso el script Livewire.on escucha al evento alert y recibe el parametro message a traves de un
callback
<button wire:click="$emit('postAdded')">
<button wire:click="$emitTo('counter', 'postAdded')">
Documentación
https://laravel-livewire.com/docs/2.x/events
La función reset permite regresar al valor inicial al conjunto de variables definidas en el arreglo que recibe como
parametro
En este caso en concreto
protected $rules = [
'title' => 'required|max:10',
'content' => 'required|min:100'
];
La propiedad protegida $rules que es un arreglo asociativo, y la función validate que ejecuta las propiedades de
dicho arreglo
Post::create([
'title' => $this->title,
'content' => $this->content
]);
$this->emitTo('show-post', 'render');
$this->emit('alert', 'El post se creó satisfactoriamente');
}
Se utiliza la función updated que recibe como parametro la propiedad y ejecuta validateOnly para validar solo
dicha propiedad
para esto se debe de permitir que la propiedad se actualize en tiempo real(sin defers)
Funcionara
El span solo se mostrara cuando se ejecute un estado loading y en especifico de la función save
esto en caso de que existan otros estados loading como por ejemplo la actualización del valor de una propiedad
publica del componente
El span estara oculto y utilizara la clase in-line-block para hacerse visible en caso de requerir otras clases para
que sea visible
se pueden especificar de la siguiente manera:
wire.loading.flex
wire.loading.grid
wire.loading.inline
wire.loading.table
wire.loading.
En el caso del danger-button este tomara la propiedad disabled usando attr despues de definir el estado de
carga loading
ademas haciendo el uso de tailwind cuando la class disabled se encuentre en ejecución se anadira una opacity
de 25
Tambien se pueden modificar las clases haciendo uso de class por ejemplo
En este caso el boton cambiara su color a azul mientras se encuentre en estado de carga loading disparado por
save
Se puede remover un elemento con la finalidad de que no sea usado mientras se encuentra en el estado de
carga
9. PARA SUBIR IMAGENES CON LIVEWIRE SE DEBE UTILIZAR EL TRAIT WITHFILEUPLOADS DENTRO
DEL CONTROLADOR DEL COMPONENTE
use Livewire\WithFileUploads;
$image = $this->image->store('posts');
Post::create([
'title' => $this->title,
'content' => $this->content,
'image' => $image
]);
...
}
Aprovechando los estados de carga se muestra un elemento mientras que la imagen es pre-cargada al servidor
<div wire:loading wire:target="image" class="mb-4 bg-red-100 border border-red-400 text-red-700 px-4 py-3
rounded relative" role="alert">
<strong class="font-bold">¡Imagen cargando!</strong>
<span class="block sm:inline">Espere un momento hasta que la imagen se haya procesado</span>
</div>
en este caso el div solo se mostrara en el estado de carga loading para la variable image del componente
de la misma manera al boton de guardado se le desactiva mientras se carga la imagen con la finalidad de evitar
un error de validación
como se puede ver el target puede recibir nombres de funciones y de valores del componente
unas ves que el usuario haya seleccionado una imagen esta se encontrara en un archivo temporal al cual se
puede acceder
para mostrar una vista previa, haciendo uso de la funcion temporaryUrl()
@if ($image)
<img class="mb-4" src="{{ $image->temporaryUrl() }}" alt="">
@endif
con la finalidad que el input de dicha imagen se limpie despues del guardado se le asigna un id aleatorio para
que livewire los considere
diferentes y entonces renderize dicho input
<div>
<input type="file" wire:model="image" id="{{ $identificador }}">
<x-jet-input-error for="error" />
</div>
...
}
Esto reseteara el valor de open title content e imagen ademas de asignar un valor nuevo al identificador del
input lo que permite que
despues del guardado se encuentre vacio
10. PARA AÑADIR MAS DE UN MISMO COMPONENTE EN UN ARCHIVO BLADE SE DEBE ENVIAR UN
KEY QUE SERIA UN VALOR UNICO IDENTIFICADOR PARA CADA
componente de esta forma livewire notaria la diferencia entre cada componente
@livewire('edit-post',['post' => $post] , key($post->id))
Se pueden utilizar las propiedades del objeto pasado en mount directamente en el blade del componente para
esto solo hay que
definir la propiedad rules del componente
En el mount se recibe a post y se define como propiedad
public function mount(Post $post)
{
$this->post = $post;
$this->identificador = rand();
}
//De esta forma se validan dichos datos
protected $rules = [
'post.title' => 'required',
'post.content' => 'required'
];
//De esta forma se accede a dichas propiedades
<x-jet-input wire:model="post.title" type="text" class="w-full" />
<textarea wire:model="post.content" rows="6" class="form-control w-full"></textarea>
//Eliminar una imagen
En caso de que se modifique un objeto que ya contenga una imagen, primero se debe eliminar la imagen de
dicho objeto
como se muestra a continuación
if($this->image){
Storage::delete([$this->post->image]);
$this->post->image = $this->image->store('posts');
}
Se pregunta si el componente tiene un valor en imagen, en caso de que si, accede al valor de la imagen y lo
elimina del Storage
despues se resguarda el valor de la variable imagen del componente como valor nuevo del post
11. PASAR PARAMETROS DE ACCIÓN
Para pasar parametros de acción se envian a traves de blade con parentesis de la siguiente manera
<a class="btn btn-green" wire:click="edit({{$item->id}})">
<i class="fas fa-edit"></i>
</a>
La función edit de dicho componente recibe como parametro una instancia de Post lo que permite pasar al item
completo
sin embargo esto ensuciara el código de forma innecesaria
<a class="btn btn-green" wire:click="edit({{$item}})">
<i class="fas fa-edit"></i>
</a>
public function edit(Post $post)
{
$this->open_edit = true;
$this->post = $post;
}
12. PAGINACIÓN
Para esto se debe utilizar la función paginate, pudiendose enviar un número de elementos en esté caso son 10
$posts = Post::where('title', 'like', '%' . $this->search . '%')
->orWhere('content', 'like', '%' . $this->search . '%')
->orderBy($this->sort, $this->direction)
->paginate(10);
De lado del blade del componente se puede mostrar el paginado haciendo uso de la función links, en este caso
tambien
se usa la función pages para mostrar entonces los links cuando sea necesario
@if ($posts->hasPages())
<div class="px-6 py-3">
{{ $posts->links() }}
</div>
@endif
13 - CICLO DE VIDA
Se le llama así a los dintintos estados por los cuales puede pasar una variable y tambien el componente
en este caso nos interesa que antes de que se ejecute el cambio de la variable search y por tanto se renderize
el componente, se
resetee la pagina y pierda los valores de su paginación y de esta forma pueda encontrar los datos que se
esperan
15 - APLAZAR CARGA
Livewire permite que el render de un componente suceda hasta que su contenedor se renderize primero, esto
permite que la página se
cargue por partes.
<div wire:init="loadPosts">
En este caso el div con wire:init="loadPosts" lo que hace es mandar a traer una función dentro del controlador
del componente que
realiza la consulta de los datos a la base de datos
//propiedad del componente
public $readyToLoad = false;
public function loadPosts()
{
$this->readyToLoad = true;
}