PHP Livewire

De MediaWiki
Ir a la navegación Ir a la búsqueda

Introducción

  • Livewire permite o uso de compoñentes integrados en Laravel nos que se establece unha comunicación bidireccional (podemos enviar información desde o cliente (HTML) ao servidor (controlador) e viceversa sen necesidade de recargar completamente a páxina).
É o mesmo concepto que se empregaba en AJAX e que agora se usa con FETCH, pero integrado no framework de Laravel.


Instalación

  • No directorio raíz do proxecto Laravel escribe: composer require livewire/livewire


Validación de campos

  • Imos crear a táboa marcas e imos crear unha relación entre perfumes e marcas.
A nivel de mysql:
CREATE TABLE perfumes.marcas (

  `id` int NOT NULL,

  `descripcion` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_spanish2_ci NOT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish2_ci;



INSERT INTO `marcas` (`id`, `descripcion`) VALUES
(1, 'Descripción actualizada da marca con id=1'),
(2, 'ADIDAS'),
(3, 'ARAMIS');


Táboa perfumes
CREATE TABLE perfumes.perfumes (
  `id` int NOT NULL,
  `descripcion` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_spanish2_ci NOT NULL,
  `prezo` decimal(8,2) NOT NULL,
  `data_compra` date DEFAULT NULL,
  `marca_id` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish2_ci;

ALTER TABLE perfumes.perfumes
  ADD PRIMARY KEY (`id`),
  ADD KEY `fk_PERFUMES_1_idx` (`id`),
  ADD KEY `fk_PERFUMES_MARCA_idx` (`marca_id`);

INSERT INTO perfumes.perfumes (`id`, `descripcion`, `prezo`, `data_compra`, `marca_id`) VALUES
(18, 'Best Aramis', '54.32', '2024-01-18', 2),
(19, 'Novo perfume da marca con id 1', '100.22', '2024-01-22', 1);



  • Creamos o modelo, ruta, controlador e polo de agora imos facer a vista para crear unha nova marca.
Dende o terminal escribimos: php artisan make:model Marca --resource


Arquivo: routes/web.php
<?php

use Illuminate\Support\Facades\Route;

use App\Http\Controllers\PerfumeController;
use App\Http\Controllers\MarcaController;

Route::resource('perfumes', PerfumeController::class);
Route::resource('marcas', MarcaController::class);


O arquivo de MarcaController xa se crearia con todo o código necesario para a xestión.


Arquivo resources/views/marcas/form_alta_marcas.blade.php (creado o cartafol marcas dentro de view)
@extends('plantilla');

@section('pageTitle', 'Alta de marcas')

@section('content')
<h2>Alta de novos perfumes</h2>



@if (session()->has('idPerfume'))
    <h4>Creado un novo rexistro co id: {{session('idPerfume')}}</h4>
@endif

@if(count($errors) > 0)
	<div class="errors">
		<ul>
		@foreach($errors->all() as $error)
			<li>{{ $error }}</li>
		@endforeach
		</ul>
	</div>
@endif


@include('mensaxes.alertas_javascript')


@endsection


  • Como fixemos con perfume, os campos que conforman o formulario en Alta e Modificar son os mesmos, polo que imos crear un arquivo para facer un include nas dúas vistas:
Arquivo: resources/views/marcas/campos_marca.blade.php
<div>
    Descipción:<input type="text" maxlength="45" size="45" value="{{!empty($perfume) ? $perfume->descripcion : old('descripcion')}}" name="descripcion" />
</div>



  • Como vemos o contido é parecido ao que tiñammos con perfumes, pero agora o contido (form e campos) os imos xestionar dende un compoñente Livewire.
Creamos o compoñente con esta orde: php artisan make:livewire marca
Isto creará dous arquivos en Laravel:
  • CLASS: app/Livewire/Marca.php => Ven a ser o controlador que vimos ata o de agora en Laravel.
  • VIEW: resources/views/livewire/marca.blade.php => Ven a ser a vista que vai visualizar Laravel no cliente.


Arquivo: app/Livewire/Marca.php
<?php

namespace App\Livewire;

use Livewire\Component;

class Marca extends Component
{
    public function render()
    {
        return view('livewire.marca');
    }
}
Básicamente indicamos en render a vista que vai enviar ao cliente.


Arquivo resource/views/Livewire/marca.blade.php
<form method="post" action="{{route('marcas.store')}}" name="formulario_marcas">

    @csrf
    @include('marcas.campos_marca')
    <div>
        <input type="submit" name="btnAlta" value="Alta" onClick="return confirm('Estás seguro de dar de alta a nova marca ');"/>
        <input type="reset" name="btnBorrar" value="Limpar" />

    </div>


</form>


  • Agora para incluir o compoñente Livewire nunha view de Laravel temos que poñer:
Arquivo resouces/views/marcas/form_alta_marca.blade.php
@extends('plantilla');

@section('pageTitle', 'Alta de marcas')

@section('content')
<h2>Alta de novos perfumes</h2>


<livewire:marca />


................


  • Se agora poñemosm na url: http://localhost:8080/marcas/create veremos que aparecerá unha vista tal cual aparecía cando fixemos o de perfume, pero a diferenza de perfumes, esta vista (os campos e form) se xestionan cun compoñente Livewire.


  • Agora imos ver os cambios que temos que facer para xestionar os campos do formulario.
Primero imos definir no controlador do compoñente livewire os campos que imos xestionar. No noso caso está a descripcion.
<?php

namespace App\Livewire;

use Livewire\Component;

class Marca extends Component
{
    public $descripcion = "Valor inicial";   // O valor inicial non é necesasrio. Soamente para que vexades como dito valor se carga na vista.

    public function render()
    {
        return view('livewire.marca');
    }
}



Arquivo: resources/views/marcas/campos_marca.blade.php
<div>
    Descipción:<input type="text" maxlength="45" size="45" wire:model="descripcion" name="descripcion" />
</div>
  • wire:model="descripcion": O que estamos a dicir con isto é que este input está vinculado á propiedade $descripcion definida no compoñente Livewire. Calquera modificación realizada polo usuario no cliente (na páxina web) actualizará automaticamente o valor da propiedade no servidor grazas á reactividade proporcionada por Livewire. Ademais, se a propiedade no servidor cambia, ese cambio tamén se reflectirá no cliente.
Se vos dades conta non temos a propiedade value como tiñamos en perfumes.
Se agora cargades a páxina veredes como o valor inicial se carga no input.



  • Agora imos a facer a validación no servidor. Para iso temos que definir unha propiedade $rules coas regras de validación que xa empregamos en Laravel.
Ademáis imos crear un método ao que vai chamar o formulario cando faga submit e que fará a validación dos campos. No exemplo imos chamar ao método gardarMarca.
Arquivo: app/Livewire/Marca.php
<?php

namespace App\Livewire;

use Illuminate\Support\Facades\Log;

use Livewire\Component;

class Marca extends Component
{
    public $descripcion = "Valor inicial";

    protected $rules = [
        'descripcion' => 'required|min:5|max:45',
    ];

    public function render()
    {
        return view('livewire.marca');
    }

    public function gardarMarca(){
        $this->validate();

        Log::info('Pasa a validación');
    }
}
Para depurar o funcionamento dos compoñente livewire é complicado xa que non podemos parar a execución ao ser un compoñente da páxina e non a páxina enteira. Podemos empregar o facade Log::info e ver as mensaxes no arquivo /storage/logs/laravel.log (podedes borrar o contido antes de executar para ter todo limpo ao principio).


  • Para chamar a ese método temos que modificar a vista do compoñente livewire.
<form wire:submit.prevent="gardarMarca">

    @csrf
    @include('marcas.campos_marca')
    <div>
        <input type="submit" name="btnAlta" value="Alta" onClick="return confirm('Estás seguro de dar de alta a nova marca ');"/>
        <input type="reset" name="btnBorrar" value="Limpar" />

    </div>


</form>
Con isto wire:submit.prevent="gardarMarca" estamos a decir que cando faga o submit chame de forma asíncrona ao controlador do compoñente livewire ao método gardarMarca.


  • Tamén imos visualizar os erros de validación que poida enviar o controlador Livewire se non pasa a validación. Para iso temos que empregar a directiva @error sobre cada un dos campos que teñen validación. No exemplo se coloca ao lado do input, pero poderían ir en calquera parte.
Arquivo: resources/views/marcas/campos_marca.blade.php
<div>
    Descipción:<input type="text" maxlength="45" size="45" wire:model="descripcion" name="descripcion" />  
    @error('descripcion') <span class="error">{{ $message }}</span> @enderror
</div>




Operacións de alta-baixa-modificación

Alta

* A alta faise como sempre pero agora está no controlador do compoñente livewire.
Arquivo: app/Livewire/Marca.php
    .............
    public function gardarMarca(){
        $this->validate();

        Log::info('Pasa a validación');

        $marcaCreada = Marca::create([
            'descripcion' => $this->descripcion
        ]);

        session()->flash('message', "Marca creada correctamente con id $marcaCreada->id");
        $this->reset(['descripcion']);
    }

: Fixarse que para enviar unha información á vista empregamos session()->flash que vai gardar nunha variable de sesión (message) o texto a amosar.
: Dita variable non pode ser empregada pola páxina, soamente polo compoñente livewire xa que non se recarga a páxina enteira.
: A chamada a reset vai poñer en branco os valor da variable $descripcion do compoñente.


Funcionamento


Volver á UD7


-- Ángel D. Fernández González -- (2025).