# Crear esquema de base de datos

Se supone que los siguientes scripts se ejecutan desde su terminal de línea de comandos.

  • Inicie sesión en la consola MySQL:
mysql -u root -p
  • Cree una base de datos de demostración:
CREATE DATABASE livewire_laravel_9;

Supongo que el usuario raíz tiene acceso completo a la base de livewire_laravel_9datos. De lo contrario, debe asignar los permisos correctamente.

# Configuración de Laravel

  • Instale un nuevo proyecto de Laravel a través de composer
composer create-project laravel/laravel livewire-laravel-9
  • Modifique las variables de entorno en el .envpara dar permisos de base de datos a:
DB_DATABASE=livewire_laravel_9
DB_USERNAME=root
DB_PASSWORD=root

Actualice su propio DB_USERNAME y DB_PASSWORD en consecuencia.

  • Inicie el servidor de desarrollo de Laravel ejecutando el siguiente comando.
cd livewire-laravel-9
php artisan serve

Debería ver la página de bienvenida predeterminada de Laravel accediendo http://127.0.0.1:8000/desde su navegador:

# Configuración de datos

Necesitamos algunos datos para demostrar el uso de la tabla HTML impulsada por Datatables. En este paso, crearemos algunos datos con el mínimo esfuerzo. Vamos a utilizar la userstabla Laravel predeterminada como fuente de datos.

  • Ejecute la migración para crear algunas tablas de base de datos predeterminadas de Laravel:
php artisan migrate
  • Cree algunos datos ficticios para la userstabla, ejecute el siguiente comando desde su terminal:
php artisan tinker 
User::factory()->count(20)->create();

Esto creará 20 registros en su userstabla.

# Configuración de Livewire

  • Instalar los paquetes de PHP
composer require livewire/livewire
  • Instalar los Activos

Cree un archivo de diseño e incluya las directivas de Balde:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="h-full">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', '') }}</title>

    
    <link rel="stylesheet" href="{{ mix('css/app.css') }}">

    @livewireStyles
</head>
<body>

<div class="max-w-4xl mx-auto mt-5">
    <div class="px-4 sm:px-6 lg:px-8">
        <h1 class="text-3xl font-black">Livewire CRUD with Laravel 9 and Tailwind CSS</h1>
    </div>
</div>


{{ $slot }}


@livewireScripts
</body>
</html>

# Configuración de Tailwind CSS

  • Instalar Tailwind CSS
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init
  • Agregue Tailwind a su configuración de Laravel Mix, abra el archivo webpack.mix.js:
mix.js("resources/js/app.js", "public/js")
  .postCss("resources/css/app.css", "public/css", [
    require("tailwindcss"),
  ]);
  • Configure las rutas de su plantilla en el archivo tailwind.config.js:
module.exports = {
  content: [
    "./resources/**/*.blade.php",
    "./resources/**/*.js",
    "./resources/**/*.vue",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
  • Agregue las directivas de Tailwind a su CSS en el archivo ./resources/css/app.css:
@tailwind base;
@tailwind components;
@tailwind utilities;
  • Ahora ejecute el siguiente comando para compilar los activos:
npm install
npm run watch

Debería ver un mensaje de Laravel Mix que indica una compilación exitosa.

# Trabajar en los componentes de Livewire

# Trabajar en el componente ShowUsers

El ShowUserscomponente es responsable de enumerar todos los usuarios.

  • Crear un nuevo ShowUserscomponente:
php artisan make:livewire ShowUsers

Se deben crear dos archivos:

  1. app/Http/Livewire/ShowUsers.php
  2. resources/views/livewire/show-users.blade.php

En file app/Http/Livewire/ShowUsers.php, simplemente buscamos todos los usersregistros y los asignamos a la vista:

<?php

namespace App\Http\Livewire;

use App\Models\User;
use Livewire\Component;

class ShowUsers extends Component
{
    public function render()
    {
        return view('livewire.show-users', [
            'users' => User::all()
        ]);
    }
}

En file resources/views/livewire/show-users.blade.php, los recorremos usersy los mostramos en una tabla, nos aseguramos de que su vista Blade solo tenga UN elemento raíz, así es como funciona Livewire:

<div class="max-w-4xl mx-auto mt-5">
    <div class="px-4 sm:px-6 lg:px-8">
        <div class="sm:flex sm:items-center">
            <div class="sm:flex-auto">
                <h1 class="text-xl font-semibold text-gray-900">Users</h1>
                <p class="mt-2 text-sm text-gray-700">A list of all the users.</p>
            </div>
            <div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
                <a href="/user/add"
                        class="inline-flex items-center justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 sm:w-auto">
                    Add user
                </a>
            </div>
        </div>
        <div class="mt-8 flex flex-col">
            <div class="-my-2 -mx-4 overflow-x-auto sm:-mx-6 lg:-mx-8">
                <div class="inline-block min-w-full py-2 align-middle md:px-6 lg:px-8">
                    <div class="overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg">
                        <table class="min-w-full divide-y divide-gray-300">
                            <thead class="bg-gray-50">
                            <tr>
                                <th scope="col"
                                    class="py-3 pl-4 pr-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500 sm:pl-6">
                                    ID
                                </th>
                                <th scope="col"
                                    class="px-3 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">
                                    Name
                                </th>
                                <th scope="col"
                                    class="px-3 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">
                                    Email
                                </th>
                                <th scope="col" class="relative py-3 pl-3 pr-4 sm:pr-6">
                                    <span class="sr-only">Edit</span>
                                </th>
                            </tr>
                            </thead>
                            <tbody class="divide-y divide-gray-200 bg-white">

                            @foreach($users as $user)
                                <tr>
                                    <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6">
                                        {{ $user->id }}
                                    </td>
                                    <td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
                                        {{ $user->name }}
                                    </td>
                                    <td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
                                        {{ $user->email }}
                                    </td>
                                    <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6">
                                        <a href="/user/edit/{{ $user->id }}"
                                            class="text-indigo-600 hover:text-indigo-900">Edit</a>
                                    </td>
                                </tr>
                            @endforeach
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

  • ShowUserses un componente de página completa, cree una ruta en routes/web.php:
Route::get('/user', ShowUsers::class);

Ahora navegue http://127.0.0.1:8000/userdesde su navegador y debería ver una bonita vista de tabla:

# Trabajar en el componente CreateUser

El CreateUser componente es responsable de crear un usuario. Cuál es la createacción en CRUD.

  • Crear un nuevo CreateUser componente:
php artisan make:livewire CreateUser

Se deben crear dos archivos:

  1. app/Http/Livewire/CreateUser.php
  2. resources/views/livewire/create-user.blade.php

En el archivo CreateUser.php, copie el contenido a continuación:

<?php

namespace App\Http\Livewire;

use App\Models\User;
use Livewire\Component;

class CreateUser extends Component
{
    public User $users ;

    protected $rules = [
        'users.name' => 'required|string|min:6',
        'users.email' => 'required|string|max:500|unique:users',
    ];

    public function mount()
    {
        $this->users = new User();
    }

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

        $this->users->password = time();

        $this->users->save();

        return redirect()->to('/user');
    }

    public function render()
    {
        return view('livewire.create-user');
    }
}

  • Almacenamos el modelo Eloquent Useren una variable pública, esto es necesario para que Livewire funcione correctamente.
  • Similar a la validación estándar de Laravel, Livewire proporciona una $rulespropiedad para que proporcionemos algunas reglas de validación.
  • En el método mount, inicializamos un Usermodelo vacío para que Livewire lo reconozca como un modelo Eloquent.
  • El método savese activa cuando se envía el formulario; en esta función, llamamos a la función de validación de Livewire, seguida de la función de guardado de Eloquent y, por último, redirigimos la página a la página de índice.
  • En el método render, simplemente renderizamos el archivo de vista, en el que vamos a trabajar a continuación.

Abra el archivo resources/views/livewire/create-user.blade.phpy copie el contenido a continuación:

<div class="max-w-4xl mx-auto mt-5">
    <div class="px-4 sm:px-6 lg:px-8">
        <form wire:submit.prevent="save">
            <div class="mb-6">
                <label for="name" class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300">Your
                    name</label>
                <input type="text"
                        wire:model="users.name"
                       class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
                       placeholder="Joh"
                       required="">
                @error('users.name') <span class="text-sm text-red-500">{{ $message }}</span> @enderror
            </div>
            <div class="mb-6">
                <label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300">Your
                    email</label>
                <input type="email"
                       wire:model="users.email"
                       class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
                       placeholder="name@flowbite.com" required="">
                @error('users.email') <span class="text-sm text-red-500">{{ $message }}</span> @enderror
            </div>
            <div class="flex items-center justify-start space-x-4">
                <a href="/user" class="text-gray-900  font-medium  text-sm ">Back</a>
                <button type="submit"
                        class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
                    Save
                </button>
            </div>
        </form>

    </div>
</div>

Un par de lugares para tomar nota:

  • <form wire:submit.prevent="save">le dice al formulario que llame al savemétodo del CreateUsercomponente.
  • Todas las variables se almacenan en el modelo Livewire, las reconoce por la wire:modelsintaxis.

Por último, agregue la siguiente ruta al routes/web.phparchivo:

Route::get('/user/add', CreateUser::class);

Ahora abra su navegador y diríjase a http://127.0.0.1:8000/user/add, debería poder ver una página de formulario de creación de usuario que funcione bien:

# Trabajar en el componente EditUser

El CreateUser componente es responsable de crear un usuario. Cuál es la createacción en CRUD.

  • Crear un nuevo CreateUser componente:
php artisan make:livewire CreateUser

Se deben crear dos archivos:

  1. app/Http/Livewire/EditUser.php
  2. resources/views/livewire/edit-user.blade.php

En el archivo EditUser.php, copie el contenido a continuación:


Este archivo es casi idéntico a app/Http/Livewire/CreateUser.php, la principal diferencia es que hemos cambiado el $rulesa un método en lugar de la propiedad original. La razón es que necesitamos excluir la identificación del usuario actual al aplicar la uniqueregla.

Abra el archivo resources/views/livewire/edit-user.blade.phpy copie el contenido a continuación:

Este archivo es idéntico a resources/views/livewire/create-user.blade.php.

Por último, agregue la siguiente ruta al routes/web.phparchivo:

Route::get('/user/edit/{user}', EditUser::class);

La {user}declaración es la clave aquí, al usar esta ruta, Livewire automáticamente ayuda a deshidratar el modelo para nosotros.

Ahora abra su navegador y diríjase http://127.0.0.1:8000/usery haga clic en el Editenlace, debería poder ver una página de formulario de edición de usuario que funciona bien:

# Trabajar en la acción Eliminar

Una última característica que falta en las CRUDacciones es el DeleteAhora abra el archivo app/Http/Livewire/ShowUsers.phpy agregue otro método:

public function delete(User $user)
{
    $user->delete();
}

Abra el archivo resources/views/livewire/show-users.blade.phpy agregue un deleteenlace justo después del editenlace:

<a href="#"
   onclick="confirm('Are you sure you want to remove the user') || event.stopImmediatePropagation()"
   wire:click="delete({{ $user->id }})"
   class="text-red-600 hover:text-red-900">Delete</a>

Ahora abra su navegador y diríjase http://127.0.0.1:8000/usery haga clic en el Deleteenlace, debería poder eliminar cualquier usuario:

# Resultado final

Ahora dirígete a http://127.0.0.1:8000/userdesde tu navegador. Debería ver una tabla HTML potenciada por Datatables que funciona muy bien:

# código fuente

Si sigue el tutorial paso a paso, obtendrá todo el código fuente en su lugar. Sin embargo, si se siente perezoso o necesita descargar el código fuente completo de nosotros. Puede hacerlo pagándonos una pequeña tarifa. Su apoyo nos permitirá producir tutoriales mejores y más detallados.