02-04-analogia-e

 

Creando Componentes en Laravel

Introducción

En este tutorial aprenderás a crear y utilizar componentes de Blade en Laravel, una herramienta fundamental para reutilizar código y mantener tus vistas limpias y organizadas.

Crearemos un componente de botón que podremos reutilizar en toda nuestra aplicación, personalizando su apariencia y comportamiento.


1. ¿Qué son los Componentes?

Los componentes son bloques de código reutilizables que encapsulan HTML y lógica. En lugar de copiar y pegar el mismo código una y otra vez, defines el componente una sola vez y lo utilizas donde lo necesites.

Beneficios:

  • ✅ Reutilización de código

  • ✅ Mantenimiento simplificado

  • ✅ Código más limpio y organizado

  • ✅ Consistencia visual en toda la aplicación


2. Creando Nuestro Primer Componente

Paso 1: Crear el componente con Artisan

bash

php artisan make:component Button

Este comando crea dos archivos:

  • app/View/Components/Button.php - Lógica PHP

  • resources/views/components/button.blade.php - Vista HTML

Paso 2: Estructura del componente

Archivo PHP (app/View/Components/Button.php):

php

<?php


namespace App\View\Components;


use Illuminate\View\Component;


class Button extends Component

{

    public function __construct()

    {

        //

    }


    public function render()

    {

        return view('components.button');

    }

}

Vista (resources/views/components/button.blade.php):

blade

<div>

    Hola mundo desde el componente

</div>

Paso 3: Usar el componente

En cualquier vista (ej. home.blade.php):

blade

<x-button />

Resultado: Verás "Hola mundo desde el componente" en tu página.


3. Añadiendo Estilos (Clases CSS)

Ahora vamos a convertir nuestro componente en un botón real con estilos.

Modificar la vista del componente:

blade

<!-- resources/views/components/button.blade.php -->

<button class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition">

    {{ $slot }}

</button>

Uso con contenido personalizado:

blade

<x-button>

    Click aquí

</x-button>


<x-button>

    Enviar formulario

</x-button>


4. Pasando Propiedades (Variables)

Para hacer que el botón pueda tener diferentes colores, necesitamos variables.

Paso 1: Definir variables en la clase PHP

php

// app/View/Components/Button.php

<?php


namespace App\View\Components;


use Illuminate\View\Component;


class Button extends Component

{

    public $type;


    public function __construct($type = 'primary')

    {

        $this->type = $type;

    }


    public function render()

    {

        return view('components.button');

    }

}

Paso 2: Usar la variable en la vista

blade

<!-- resources/views/components/button.blade.php -->

@php

    $colors = [

        'primary' => 'bg-blue-500 hover:bg-blue-600',

        'success' => 'bg-green-500 hover:bg-green-600',

        'danger' => 'bg-red-500 hover:bg-red-600',

        'warning' => 'bg-yellow-500 hover:bg-yellow-600',

        'dark' => 'bg-gray-700 hover:bg-gray-800',

    ][$type] ?? 'bg-blue-500 hover:bg-blue-600';

@endphp


<button class="px-4 py-2 text-white rounded-lg transition {{ $colors }}">

    {{ $slot }}

</button>

Paso 3: Usar el componente con tipo

blade

<x-button type="success">

    Guardar

</x-button>


<x-button type="danger">

    Eliminar

</x-button>


<x-button type="warning">

    Advertencia

</x-button>


5. Pasando Atributos HTML

Los atributos que no están definidos en la clase PHP se almacenan automáticamente en $attributes.

Modificar la vista para aceptar atributos:

blade

<!-- resources/views/components/button.blade.php -->

@php

    $colors = [

        'primary' => 'bg-blue-500 hover:bg-blue-600',

        'success' => 'bg-green-500 hover:bg-green-600',

        'danger' => 'bg-red-500 hover:bg-red-600',

        'warning' => 'bg-yellow-500 hover:bg-yellow-600',

        'dark' => 'bg-gray-700 hover:bg-gray-800',

    ][$type] ?? 'bg-blue-500 hover:bg-blue-600';

@endphp


<button 

    {{ $attributes->merge(['class' => "px-4 py-2 text-white rounded-lg transition $colors"]) }}

>

    {{ $slot }}

</button>

Uso con atributos personalizados:

blade

<x-button type="success" id="btn-guardar" name="guardar">

    Guardar

</x-button>


<x-button type="danger" id="btn-eliminar" onclick="confirmarEliminacion()">

    Eliminar

</x-button>

Resultado en HTML:

html

<button id="btn-guardar" name="guardar" class="px-4 py-2 text-white rounded-lg transition bg-green-500 hover:bg-green-600">

    Guardar

</button>


6. Agregando Clases Adicionales con Merge

El método merge permite combinar clases por defecto con clases adicionales que se pasan desde la vista.

Modificar el componente:

blade

<!-- resources/views/components/button.blade.php -->

@php

    $colors = [

        'primary' => 'bg-blue-500 hover:bg-blue-600',

        'success' => 'bg-green-500 hover:bg-green-600',

        'danger' => 'bg-red-500 hover:bg-red-600',

        'warning' => 'bg-yellow-500 hover:bg-yellow-600',

        'dark' => 'bg-gray-700 hover:bg-gray-800',

    ][$type] ?? 'bg-blue-500 hover:bg-blue-600';

@endphp


<button 

    {{ $attributes->merge([

        'class' => "px-4 py-2 text-white rounded-lg transition $colors"

    ]) }}

>

    {{ $slot }}

</button>

Uso con clases adicionales:

blade

<!-- Clase extra para separación -->

<x-button type="success" class="mb-4">

    Guardar

</x-button>


<x-button type="danger" class="mt-2 ml-4">

    Eliminar

</x-button>

Resultado: Se combinan las clases por defecto con la clase adicional.


7. Usando Slots

Los slots permiten pasar contenido dinámico al componente.

Modificar el componente con slot:

blade

<!-- resources/views/components/button.blade.php -->

@php

    $colors = [

        'primary' => 'bg-blue-500 hover:bg-blue-600',

        'success' => 'bg-green-500 hover:bg-green-600',

        'danger' => 'bg-red-500 hover:bg-red-600',

        'warning' => 'bg-yellow-500 hover:bg-yellow-600',

        'dark' => 'bg-gray-700 hover:bg-gray-800',

    ][$type] ?? 'bg-blue-500 hover:bg-blue-600';

@endphp


<button 

    {{ $attributes->merge([

        'class' => "px-4 py-2 text-white rounded-lg transition $colors"

    ]) }}

>

    {{ $slot }}

</button>

Uso con diferentes textos:

blade

<x-button type="success" class="mb-4">

    <i class="fas fa-save"></i> Guardar Cambios

</x-button>


<x-button type="danger" class="ml-2">

    <i class="fas fa-trash"></i> Eliminar Registro

</x-button>


<x-button type="warning">

    ⚠️ Advertencia

</x-button>


8. Componente Completo con Múltiples Funcionalidades

Clase PHP completa:

php

// app/View/Components/Button.php

<?php


namespace App\View\Components;


use Illuminate\View\Component;


class Button extends Component

{

    public $type;

    public $size;


    public function __construct($type = 'primary', $size = 'md')

    {

        $this->type = $type;

        $this->size = $size;

    }


    private function getSizeClasses()

    {

        return [

            'sm' => 'px-3 py-1.5 text-sm',

            'md' => 'px-4 py-2 text-base',

            'lg' => 'px-6 py-3 text-lg',

        ][$this->size] ?? 'px-4 py-2 text-base';

    }


    private function getColorClasses()

    {

        return [

            'primary' => 'bg-blue-500 hover:bg-blue-600 focus:ring-blue-300',

            'success' => 'bg-green-500 hover:bg-green-600 focus:ring-green-300',

            'danger' => 'bg-red-500 hover:bg-red-600 focus:ring-red-300',

            'warning' => 'bg-yellow-500 hover:bg-yellow-600 focus:ring-yellow-300',

            'dark' => 'bg-gray-700 hover:bg-gray-800 focus:ring-gray-300',

            'outline' => 'bg-transparent border-2 border-blue-500 text-blue-500 hover:bg-blue-50',

        ][$this->type] ?? 'bg-blue-500 hover:bg-blue-600 focus:ring-blue-300';

    }


    public function render()

    {

        return view('components.button');

    }

}

Vista del componente:

blade

<!-- resources/views/components/button.blade.php -->

@php

    $baseClasses = 'font-medium rounded-lg transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2';

    $sizeClasses = $this->getSizeClasses();

    $colorClasses = $this->getColorClasses();

@endphp


<button 

    {{ $attributes->merge([

        'class' => "$baseClasses $sizeClasses $colorClasses"

    ]) }}

>

    {{ $slot }}

</button>

Uso avanzado:

blade

<!-- Botón primario grande -->

<x-button type="primary" size="lg" class="mb-4">

    <i class="fas fa-plus"></i> Crear Nuevo

</x-button>


<!-- Botón de éxito mediano -->

<x-button type="success" size="md" id="btn-submit">

    ✅ Aceptar

</x-button>


<!-- Botón de peligro pequeño -->

<x-button type="danger" size="sm" onclick="return confirm('¿Estás seguro?')">

    🗑️ Eliminar

</x-button>


<!-- Botón outline -->

<x-button type="outline" size="md">

    Cancelar

</x-button>


9. Ejemplos de Componentes en Laravel Breeze

Laravel Breeze incluye varios componentes preconstruidos que puedes estudiar:

Dropdown Component:

blade

<!-- Ejemplo de componente dropdown -->

<x-dropdown align="right" width="48">

    <x-slot name="trigger">

        <button class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 bg-white hover:text-gray-700 focus:outline-none transition ease-in-out duration-150">

            <div>Opciones</div>

            <div class="ml-1">

                <svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">

                    <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />

                </svg>

            </div>

        </button>

    </x-slot>


    <x-slot name="content">

        <div class="block px-4 py-2 text-xs text-gray-400">

            Mi Cuenta

        </div>

        <x-dropdown-link href="{{ route('profile.edit') }}">

            Perfil

        </x-dropdown-link>

        <x-dropdown-link href="{{ route('logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">

            Cerrar Sesión

        </x-dropdown-link>

    </x-slot>

</x-dropdown>


10. Buenas Prácticas y Consejos

1. Nombres de componentes

  • Usa nombres descriptivos: PrimaryButton, AlertBox, UserCard

  • Sigue el estilo kebab-case para archivos: primary-button.blade.php

2. Documentación

blade

{{-- 

    Componente: Button

    Props:

    - type: primary|success|danger|warning|dark|outline (default: primary)

    - size: sm|md|lg (default: md)

    - slot: Contenido del botón

--}}

3. Organización

text

resources/views/components/

├── buttons/

│   ├── primary.blade.php

│   ├── danger.blade.php

│   └── success.blade.php

├── forms/

│   ├── input.blade.php

│   └── select.blade.php

└── layouts/

    └── app.blade.php

4. Reutilización entre proyectos

Crea un paquete de componentes para usar en múltiples proyectos:

bash

# Crear un paquete con componentes comunes

php artisan vendor:publish --tag=components


11. Resumen

Ventajas de usar componentes:

Aspecto

Beneficio

Código

Más limpio y organizado

Mantenimiento

Cambios en un solo lugar

Consistencia

Misma apariencia en toda la app

Productividad

Menos código duplicado

Flexibilidad

Fácil personalización

Comandos útiles:

bash

# Crear componente

php artisan make:component Nombre


# Crear componente en subcarpeta

php artisan make:component Forms/Input


# Ver todos los componentes

php artisan component:list


# Eliminar componente

php artisan make:component Nombre --force


12. Ejercicio Práctico

Crea un componente de tarjeta que:

  1. Tenga un título personalizable

  2. Tenga contenido variable

  3. Pueda tener diferentes colores de borde

  4. Acepte clases adicionales

Solución:

blade

<!-- resources/views/components/card.blade.php -->

@props(['title' => null, 'color' => 'blue'])


@php

    $colors = [

        'blue' => 'border-blue-500',

        'green' => 'border-green-500',

        'red' => 'border-red-500',

        'yellow' => 'border-yellow-500',

    ][$color] ?? 'border-blue-500';

@endphp


<div {{ $attributes->merge(['class' => "border-l-4 $colors bg-white shadow-md rounded-lg p-6"]) }}>

    @if($title)

        <h3 class="text-lg font-semibold mb-4">{{ $title }}</h3>

    @endif

    {{ $slot }}

</div>

Uso:

blade

<x-card title="Notificación" color="yellow" class="mb-4">

    <p>Este es el contenido de la tarjeta.</p>

</x-card>


<x-card color="green">

    <p>Tarjeta sin título.</p>

</x-card>


Conclusión

Los componentes de Blade son una herramienta poderosa que te permite:

  1. Crear interfaces reutilizables

  2. Mantener código limpio y organizado

  3. Ahorrar tiempo en desarrollo

  4. Facilitar el mantenimiento

¡Comienza a crear tus propios componentes y mejora tu flujo de trabajo en Laravel!


Comentarios

Entradas más populares de este blog

02 -Rutas en Laravel

01-04-convencion nombres

1-4-Evolución en PHP Puro-Credenciales en Body/Query String: