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:
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:
Tenga un título personalizable
Tenga contenido variable
Pueda tener diferentes colores de borde
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:
Crear interfaces reutilizables
Mantener código limpio y organizado
Ahorrar tiempo en desarrollo
Facilitar el mantenimiento
¡Comienza a crear tus propios componentes y mejora tu flujo de trabajo en Laravel!
Comentarios
Publicar un comentario