LIVEWERE

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 14

1.

PARA CREAR UN COMPONENTE DE LARAVEL SE USA EL SIGUIENTE COMANDO

php artisan make:livewire nombreDelComponente

También se puede pasar el nombre de una carpeta donde deberá generarse dicho componente, por
ejemplo

php artisan make:livewire Carpeta/nombreDelComponente

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

Esto generara dos archivos el primero en

app/Http/Livewire

y el segundo en

resources/views/livewire

siendo estos según el comando

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

- El archivo php sería el equivalente a un controlador

- 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;

public function mount($title)


{
$this->titulo = $title;
}

Esto permitirá recibir el valor como title @livewire('nombre-del-componente',['title'=>'Este es un valor']) y luego


hacer uso de el
usando la variable 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

Route::get('/dashboard',ShowPosts::class)->name('dashboard'); <-- Ruta que usa el 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

public function render()


{
return view('livewire.show-posts')
->layout('layouts.base');
}

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')

- En caso de que el componente se encuentre dentro de una carpeta se debe especificar


@livewire('carpeta.nombre-del-componente')

- Para enviar datos a un componente se usa un arreglo asociativo @livewire('nombre-del-componente',


['title'=>'Este es un valor'])[1]

- Para enviar datos a un componente que se usa como controlador y uno archivo en una vista

use App\Http\Livewire\ShowPosts; <-- Controlador del componente

Route::get('prueba/{name}',ShowPosts::class);

y se utiliza el método mount

public $name;
public function mount($name){
$this->name = $name;
}

de esta forma es accesible desde la vista del componente

4. LIVEWIRE PERMITE AÑADIR ACCIONES EN EL CÓDIGO HTML ESCRITO EN BLADE

<th class="cursor-pointer" wire:click="order('title')">


<th class="cursor-pointer" wire:click="order('content')">

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

public function order($sort)


{
if ($this->sort == $sort) {
if ($this->direction == 'desc') {
$this->direction = 'asc';
} else {
$this->direction = 'desc';
}
} else {
$this->sort = $sort;
$this->direction = 'asc';
}
}
}

Es decir el parámetro que se está enviando es $sort

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

@if ($sort == 'title')


@if($direction =='asc')
<i class="fas fa-sort-alpha-up-alt float-right mt-1"></i>
@else
<i class="fas fa-sort-alpha-down-alt float-right mt-1"></i>
@endif

@else
<i class="fas fa-sort float-right mt-1"></i>
@endif

--Instalación de fontawesome laravel jetstream

1.- First, set up webpack.mix.js as follows:

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:

npm install --save @fortawesome/fontawesome-free


3.- Create a new file "resources/sass/app.scss" and include the following:

@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:

npm install && npm run dev


and again
npm run dev

5. <!-- MÉTODOS MÁGICOS -->

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

<!-- Defer -->

Se usa para evitar que livewire envie peticiones para actualizar cambios de un valor del controlador del
componente por ejemplo

<x-jet-input type="text" class="w-full" wire:model.defer="title" />

<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

<!-- Añadir valores con laravel mix a css -->

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

npm run dev

ahora se podra utilizar la clase .form-control


6. <!-- EVENTOS Y OYENTES -->

Para comunicar componentes se debe usar los metodos emit y la propiedad listener

<!-- Emitir evento -->

Esto enviara al componente show-post el evento render


$this->emitTo('show-post', 'render');

donde

$this->emitTo('componente que escucha','evento-que-se-envia');

Esto emitira el evento alert con el mensaje 'El posts...'


$this->emit('alert', 'El post se creó satisfactoriamente');

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');

<!-- Escuchar evento -->

Para escuchar eventos dentro de un controlador de un componente se debe usar la propiedad listeners que es
un arreglo

protected $listeners = ['render'=>'render'];


['evento-que-escucha'=>'función-que-ejecuta']

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

protected $listeners = ['render'];

Esto escuchara el evento render y ejecutara la función render

Se pueden emitir y escuchar eventos desde blade haciendo uso de scripts

<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

De la misma forma se pueden emitir eventos desde blade por ejemplo

<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 -->

$this->reset(['open', 'title', 'content']);

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

public $open = false;

public $title, $content;

Open regresara a false mientras que title y content regresaran a undefined

7. PARA VALIDAR USANDO LIVEWIRE SE UTILIZAN UNA FUNCIÓN Y UNA PROPIEDAD

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

public function save()


{
$this->validate(); <------- Validación

Post::create([
'title' => $this->title,
'content' => $this->content
]);

$this->reset(['open', 'title', 'content']);

$this->emitTo('show-post', 'render');
$this->emit('alert', 'El post se creó satisfactoriamente');
}

En este caso no guardara si $this->validate regresa errores

<!-- Validación en tiempo real -->

public function updated($propertyName)


{
$this->validateOnly($propertyName);
}

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

<x-jet-input type="text" class="w-full" wire:model="title" />


No funcionara

<textarea class="form-control w-full" rows="6" wire:model.defer="content"></textarea>

8. EN ESTE CASO SE ESPERA EL ESTADO DE CARGA LOADING

<span wire:loading wire:target="save">Cargando...</span>

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

<x-jet-danger-button wire:click="save" wire:loading.attr="disabled" wire:target="save" class="disabled:opacity-


25">
Crear post
</x-jet-danger-button>

Tambien se pueden modificar las clases haciendo uso de class por ejemplo

<x-jet-danger-button wire:click="save" wire:loading.class="bg-blue-500" wire:target="save">


Crear post
</x-jet-danger-button>

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

<x-jet-danger-button wire:click="save" wire:loading.remove wire:target="save">


Crear post
</x-jet-danger-button>

9. PARA SUBIR IMAGENES CON LIVEWIRE SE DEBE UTILIZAR EL TRAIT WITHFILEUPLOADS DENTRO
DEL CONTROLADOR DEL COMPONENTE

use Livewire\WithFileUploads;

class CreatePost extends Component


{
...
use 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

<x-jet-danger-button wire:click="save" wire:loading.attr="disabled" wire:target="save, image"


class="disabled:opacity-25">
Crear post
</x-jet-danger-button>

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>

public function mount()


{
$this->identificador = rand();
}

public function save()


{
...

$this->reset(['open', 'title', 'content','image']);


$this->identificador = rand();

...
}

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

public function updatingSearch()


{
$this->resetPage();
}

Esto afectara directamente a search


public function render()
{
$posts = Post::where('title', 'like', '%' . $this->search . '%')
->orWhere('content', 'like', '%' . $this->search . '%')
->orderBy($this->sort, $this->direction)
->paginate(10);
return view('livewire.show-posts', compact('posts'));
}
Mas información acerca de los hooks de livewire
https://laravel-livewire.com/docs/2.x/lifecycle-hooks
14. SE LE LLAMA QUERYSTRING AL HECHO DE ENVIAR PARAMETROS A TRAVES DEL ENLACE DE LA
PÁGINA DE ESTA FORMA SE PUEDE COMPARTIR EL ENLACE Y QUE OTRA PERSONA PUEDA VER
EXACTAMENTE LOS MISMOS DATOS YA QUE LOS PARAMETROS DE DICHO ENLACE AFECTAN A LA
LOGICA DEL COMPONENTE Y SU ESTADO
public $queryString = [
'cant',
'sort',
'direction',
'search'
];
Se define una propiedad publica llamada queryString donde se puede utilizar un arreglo que defina las
propiedades que deben
mostrarse en el enlace, ademas pasandole un arreglo asociativo se puede definir que valores no mostrar en el
enlace
de esta forma por ejemplo no se mostrara el valor de cant cuando este sea 10(string) o el valor de sort cuando
sea id
public $queryString = [
'cant' => ['except' =>'10'],
'sort' => ['except' =>'id'],
'direction' => ['except' =>'desc'],
'search' => ['except' =>'']
]

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;
}

Lo que cambia el valor de la propiedad readyToLoad y permite así que se busque a la bd


public function render()
{
if ($this->readyToLoad) {
$posts = Post::where('title', 'like', '%' . $this->search . '%')
->orWhere('content', 'like', '%' . $this->search . '%')
->orderBy($this->sort, $this->direction)
->paginate($this->cant);
}else{
$posts = [];
}
return view('livewire.show-posts', compact('posts'));
}
16. CKEDITOR
Para utilizar el plugin se debe integrar el CDN en un stack, en este caso en el archivo principal app.blade.php
@stack('js')
El el archivo donde se usa el editor en este caso create-post se utiliza la directiva push
@push('js')
<script src="https://cdn.ckeditor.com/ckeditor5/31.0.0/classic/ckeditor.js"></script>
<script>
ClassicEditor
.create( document.querySelector( '#editor' ) )
.then(function(editor){
editor.model.document.on('change:data',()=>{
@this.set('content',editor.getData());
});
})
.catch( error => {
console.error( error );
} );
</script>
@endpush
<div class="mb-4">
<x-jet-label value="Contenido del post" />
<div wire:ignore>
<textarea id="editor" class="form-control w-full" rows="6"
wire:model.defer="content">{{$content}}</textarea>
</div>
<x-jet-input-error for="content" />
</div>
Se añade wire:ignore con la finalidad de que cada ves que renderize ignore la zona que tiene cargado al plugin
Se incluye a Ckeditor con su CDN, despues de eso con then se recibe al editor, en cada cambio de dicho editor
se utiliza a @this.set() para definir que el contenido se tomara del editor.getData
17. PARA UTILIZAR LA CONFIRMACIÓN DE SWEATALERT SE UTILIZA LA EMISIÓN Y ESCUCHA DE
EVENTOS
En el boton de eliminar se añade lo siguiente, la emisión del evento deletePost, enviando el id del post como
parametro
<a class="btn btn-red ml-2" wire:click="$emit('deletePost',{{ $item->id }})">
<i class="fas fa-trash"></i>
</a>
En javaScript de escucha el evento deletePost recibiendo el parametro postId con lo cual utiliza un callback
en el cual levanta la confirmación que ofrece sweatAlert, despues en caso de recibir una confirmación se emite
otro evento
esta ves directamente desde javaScript usando Livewire.emitTo('componente','evento','parametro')
<script>
Livewire.on('deletePost', postId => {
Swal.fire({
title: 'Are you sure?',
text: "You won't be able to revert this!",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!'
}).then((result) => {
if (result.isConfirmed) {
Livewire.emitTo('show-posts', 'delete', postId);
Swal.fire(
'Deleted!',
'Your file has been deleted.',
'success'
)
}
})
})
</script>

También podría gustarte