Aprende Laravel: Componentes de Blade

En el post de vistas y layouts viste los fundamentos de Blade. Ahora vamos al patrón que más te va a ahorrar código: los componentes son piezas de UI reutilizables que usas como si fueran etiquetas HTML (<x-alert/>). En vez de copiar el mismo bloque de markup por todo el proyecto, lo defines una vez y lo reutilizas.
Dos tipos de componentes
- Anónimos: solo un archivo Blade en
resources/views/components. Perfectos para UI sin lógica. - De clase: una clase PHP + su vista, para cuando el componente necesita lógica.
Se crean con Artisan:
php artisan make:component AlertEso genera la clase en app/View/Components/Alert.php y la vista en resources/views/components/alert.blade.php. Puedes anidar con carpetas:
php artisan make:component Forms/InputRenderizar un componente
Se usan con el prefijo x- seguido del nombre en kebab-case:
<x-alert/>
<x-forms.input/>Pasar datos: atributos y props
Los atributos simples se pasan como en HTML. Para pasar una variable o expresión PHP, antepón : al nombre:
<x-alert type="error" :message="$message"/>En un componente anónimo, declaras qué props espera con la directiva @props al tope de la vista (con valores por defecto opcionales):
@props(['type' => 'info', 'message'])
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>En un componente de clase, las propiedades públicas de la clase quedan disponibles en la vista automáticamente.
Slots: contenido dinámico dentro del componente
El contenido que pones entre las etiquetas del componente llega como el slot por defecto, {{ $slot }}:
{{-- Uso --}}
<x-alert>
Algo salió mal.
</x-alert>
{{-- resources/views/components/alert.blade.php --}}
<div class="alert">
{{ $slot }}
</div>Y puedes tener slots nombrados para varias zonas:
{{-- Uso --}}
<x-alert>
<x-slot:title>Error</x-slot>
No se pudo guardar.
</x-alert>
{{-- Componente --}}
<div class="alert">
<h4>{{ $title }}</h4>
{{ $slot }}
</div>El attribute bag: reenviar atributos
Cuando renderizas <x-alert class="mt-4"/>, ese class extra no aparece solo: lo controlas con $attributes. Lo más útil es merge(), que combina tus clases fijas con las que pasen desde afuera:
<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
{{ $message }}
</div>Así el componente trae sus estilos base y quien lo usa puede sumar los suyos sin romper nada. Para clases condicionales, tienes ->class([...]):
<div {{ $attributes->class(['p-4', 'bg-red' => $hasError]) }}>
{{ $message }}
</div>Siguiente Paso
Ya sabes construir UI reutilizable. Toca conocer la herramienta que usaste todo el tiempo sin detenerte a mirarla: la consola de Laravel. Sigue con Aprende Laravel: Artisan.
Preguntas Frecuentes
¿Cuál es la diferencia entre un componente anónimo y uno de clase?
El anónimo es solo un archivo Blade (ideal para UI sin lógica). El de clase tiene además una clase PHP donde poner lógica y propiedades. Empieza por anónimos y pasa a clase cuando necesites lógica.
¿Cómo paso una variable a un componente?
Con : delante del atributo: <x-alert :message="$message"/>. Sin : el valor se toma como texto literal.
¿Qué es un slot?
El contenido que pones entre las etiquetas del componente. El slot por defecto es {{ $slot }}; también puedes tener slots nombrados con <x-slot:nombre>.
¿Para qué sirve $attributes->merge()?
Para combinar los atributos (como class) que trae el componente con los que le pasa quien lo usa, sin pisarlos. Es lo que hace que un componente sea flexible.