CRUD completo con Livewire 4 y Laravel 12 en un solo archivo (Single-File Component)
Tutorial paso a paso para crear un CRUD con Livewire 4 en Laravel 12 usando Single-File Components: lista de posts, crear, editar, eliminar, validación reactiva y mensaje
INDICE
Hoy vamos a crear un CRUD básico pero funcional de posts (título + contenido) usando Livewire 4 junto con Laravel 12, aprovechando una de las características más potentes de Livewire 4: los Single-File Components (todo el componente en un solo archivo PHP + su vista Blade asociada).
¿Qué vamos a lograr en este tutorial?
- Mostrar una lista de posts con paginación manual (carga todos los últimos primero)
- Crear un post nuevo
- Editar un post existente
- Eliminar un post con confirmación
- Validación en tiempo real con wire:model.live
- Mensajes de éxito con session()->flash
- Cambiar entre modos (lista / crear / editar) sin recargar la página
- Todo en un solo componente Livewire, sin necesidad de controladores ni rutas extras
Ventajas que vamos a aprovechar de Livewire 4:
- Lógica y vista muy cercanas (menos saltos entre archivos)
- Validación automática y reactiva
- Comunicación bidireccional con el servidor sin escribir JavaScript
- Simplicidad extrema para aplicaciones internas, paneles de administración o prototipos rápidos
Requisitos previos
- Laravel 12 instalado
- Livewire 4 instalado (composer require livewire/livewire)
- Modelo Post con migración (title string, content text)
Paso 1: Crear el componente
Ejecuta:
php artisan make:livewire posts
Esto crea:
- app/Livewire/Posts.php
- resources/views/livewire/posts.blade.php
Paso 2: Código completo del componente (Posts.php) PHP
<?phpnamespace App\Livewire;use Livewire\Component; use App\Models\Post;class Posts extends Component { public string $mode = "list"; // list - create - editpublic $posts; public $postId = null; public $title = ""; public $content = "";// ──────────────────────────────────────────────── // FUNCIONES EXPLICADAS // ────────────────────────────────────────────────/** * Se ejecuta al montar el componente (primera carga) */ public function mount() { $this->loadPosts(); }/** * Carga TODOS los posts desde la base de datos * (se usa cada vez que necesitamos refrescar la lista) */ public function loadPosts() { $this->posts = Post::latest()->get(); }/** * Prepara el formulario para CREAR un post nuevo * Limpia los campos y cambia el modo a "create" */ public function showCreate() { $this->resetForm(); $this->mode = "create"; }/** * Carga los datos de un post existente para editarlo * @param int $id ID del post a editar */ public function showEdit($id) { $post = Post::findOrFail($id); $this->postId = $post->id; $this->title = $post->title; $this->content = $post->content; $this->mode = "edit"; }/** * Guarda o actualiza el post (función principal del CRUD) * - Valida los datos * - Si hay $postId → actualiza * - Si no hay → crea nuevo */ public function save() { $this->validate();if ($this->postId) { // Actualizar post existente Post::find($this->postId)->update([ 'title' => $this->title, 'content' => $this->content ]); session()->flash('status', 'Post actualizado correctamente'); } else { // Crear post nuevo Post::create([ 'title' => $this->title, 'content' => $this->content, ]); session()->flash('status', 'Post creado correctamente'); }$this->resetForm(); $this->mode = "list"; $this->loadPosts(); }/** * Elimina un post de la base de datos * @param int $id ID del post a eliminar */ public function delete($id) { $post = Post::findOrFail($id)->delete(); session()->flash('status', 'Post eliminado correctamente'); $this->loadPosts(); }/** * Define las reglas de validación (Livewire las usa automáticamente) */ public function rules(): array { return [ 'title' => ['required', 'string', 'min:3', 'max:100'], 'content' => ['required', 'string', 'min:10'], ]; }/** * Limpia el formulario y quita los errores de validación * (muy útil para reutilizar entre crear y editar) */ private function resetForm() { $this->reset(['postId', 'title', 'content']); $this->resetValidation(); }public function render() { return view('livewire.posts'); } }
Paso 3: La vista (posts.blade.php) – sin cambios blade
<div> @if (session('status')) <div>{{session('status')}}</div> @endif@if ($mode==="list") <h1>Mis Posts</h1> <button wire:click="showCreate">+ Nuevo post</button> <!-- LIST--> <table> <thead> <tr> <th>Título</th> <th>Contenido</th> <th>Acciones</th> </tr> </thead> <tbody> @forelse($posts as $post) <tr> <td>{{ $post->title }}</td> <td>{{ Str::limit($post->content, 90) }}</td> <td> <button wire:click="showEdit({{ $post->id }})">Editar</button> <button wire:click="delete({{ $post->id }})" onclick="return confirm('¿Seguro que quieres eliminar este post?')">Eliminar</button> </td> </tr> @empty <tr> <td colspan="3">No hay posts aún. Crea uno con el botón de arriba.</td> </tr> @endforelse </tbody> </table> @elseif($mode==="create" || $mode==="edit") <!-- FORM --> <h1>{{ $mode === 'create' ? 'Crear Nuevo Post' : 'Editar Post' }}</h1> <form wire:submit="save"> <div> <label>Título</label> <input wire:model.live="title" type="text"> @error('title') <div>{{ $message }}</div> @enderror </div> <div> <label>Contenido</label> <textarea wire:model.live="content" rows="1"></textarea> @error('content') <div>{{ $message }}</div> @enderror </div> <div> <button type="submit">{{ $mode === 'create' ? 'Guardar Post' : 'Actualizar Post' }}</button> <button type="button" wire:click="cancel">Cancelar</button> </div> </form>@endif </div>
Resumen de lo que hace cada parte principal
- mount() → carga inicial de posts
- loadPosts() → refresca la lista siempre que cambie algo
- showCreate() → limpia y abre formulario nuevo
- showEdit($id) → carga datos del post y abre modo edición
- save() → crea o actualiza + mensaje + vuelve a lista
- delete($id) → elimina + mensaje + refresca
- rules() → validaciones automáticas de Livewire
- resetForm() → limpia campos y errores
- cancel() → regresa a lista sin guardar
¿Cómo usarlo?
- Agrega la ruta en web.php:
PHP
// livewire - crud posts
Route::livewire('/posts','post-crud');
- Visita /posts
- ¡Listo! Tienes un CRUD reactivo sin escribir JavaScript ni controladores.
¿Qué te parece? ¿Quieres que en la siguiente parte agreguemos búsqueda en vivo, paginación real con WithPagination, o subida de imágenes?
¡Cuéntame en los comentarios! 🚀
#Laravel #Livewire #Livewire4 #Laravel12 #PHP
Leido 35 veces | 0 usuarios
CRUD completo con Livewire 4 y Laravel 12 en un solo archivo (Single-File Component)
Accede al código fuente esencial de nuestra aplicación en formato ZIP ó TXT. Ideal para desarrolladores que desean personalizar o integrar nuestra solución.
- [ Pago: Paypal ]
- [ Precio: USD 5.00 ]
- [ Descargas: 0 ]
CÓDIGO FUENTE: USD 5.00
Conversar con J.Luis