02-03-componente-ejer
Definición del componente (layout)s
Este es el archivo del componente donde se define el slot principal y las propiedades.
resources/views/components/layout.blade.php:
@props(['title' => 'Mi App']) <!-- Propiedad con valor por defecto -->
<html>
<head>
<title>{{ $title }}</title>
</head>
<body>
<header>Mi sitio web</header>
<main>
{{ $slot }} <!-- Aquí se inyectará TODO -->
</main>
<footer>© 2026</footer>
</body>
</html>
Explicación:
@props(['title' => 'Mi App']) define una propiedad title con valor por defecto.
{{ $slot }} es el hueco principal donde se renderizará todo el contenido interno del componente.
2️⃣ Uso del componente (vista hija)
Este es el archivo donde usas el componente y le pasas contenido.
resources/views/home.blade.php:
<x-layout title="Lista de tareas">
<h1>¡Bienvenido!</h1>
<ul>
<li>Tarea 1</li>
</ul>
</x-layout>
Explicación:
El atributo title="Lista de tareas" se pasa a la propiedad $title del componente.
Todo el contenido entre <x-layout> y </x-layout> (el <h1> y la <ul>) se inyectará automáticamente en {{ $slot }} del layout.
3️⃣ Representación / Resultado renderizado
Cuando Laravel procesa la vista, genera este HTML final:
<html>
<head>
<title>Lista de tareas</title>
</head>
<body>
<header>Mi sitio web</header>
<main>
<h1>¡Bienvenido!</h1>
<ul>
<li>Tarea 1</li>
<li>Tarea 2</li>
<li>Tarea 3</li>
</ul>
</main>
<footer>© 2026</footer>
</body></html>
Observa:
El <title> tomó el valor del atributo title.
El contenido interno (<h1> y <ul>) apareció dentro de <main>, exactamente donde estaba {{ $slot }}.
🎯 ¿Qué cambia?
Te explico paso a paso para que quede claro como el agua. 💧
🧩 ¿Y si tengo dos componentes padres en la misma página?
Cada componente tiene su propio $slot. Cuando anidas componentes:
blade
<x-layout>
<x-card>
<x-alert>Mensaje</x-alert>
</x-card>
</x-layout>
El $slot de layout recibe el HTML generado por card.
El $slot de card recibe el HTML generado por alert.
El $slot de alert recibe el texto "Mensaje".
Cada $slot vive en el contexto de su propio componente, no hay conflicto porque cada componente renderiza su contenido y lo pasa al padre.
✅ Conclusión final
$slot = contenido principal (el que va directamente dentro del componente).
Slots con nombre (<x-slot name="...">) = props que contienen HTML (como sidebar, footer, etc.).
No necesitas llamar $slot de otra forma porque es el nombre predeterminado para el "children" del componente.
Cada componente tiene su propio $slot, por lo que al anidar no hay
Analogía rápida
🎯 Ejemplo práctico: Un Card
🔹 En React (funcional)
jsx
// Card.jsx
function Card({ title, children }) {
return (
<div className="card">
<h2>{title}</h2>
<div className="body">{children}</div>
</div>
);
}
// Uso
<Card title="Mi título">
<p>Contenido del card</p>
</Card>
🔹 En Blade (componente simple)
blade
<!-- resources/views/components/card.blade.php -->
@props(['title']) <!-- Definimos props -->
<div class="card">
<h2>{{ $title }}</h2>
<div class="body">{{ $slot }}</div> <!-- slot = children -->
</div>
<!-- Uso -->
<x-card title="Mi título">
<p>Contenido del card</p>
</x-card>
🧩 Slots con nombre (equivale a props con JSX)
🔹 En React
jsx
function Layout({ sidebar, children }) {
return (
<div>
<aside>{sidebar}</aside>
<main>{children}</main>
</div>
);
}
<Layout sidebar={<Sidebar />}>
<h1>Contenido principal</h1>
</Layout>
🔹 En Blade
blade
<!-- layout.blade.php -->
@props(['sidebar' => null])
<div>
<aside>{{ $sidebar }}</aside>
<main>{{ $slot }}</main>
</div>
<!-- Uso -->
<x-layout>
<x-slot name="sidebar">
<aside>Sidebar personalizado</aside>
</x-slot>
<h1>Contenido principal</h1>
</x-layout>
Ejemplo de múltiples slots en un mismo layout (si te interesa)
blade
<!-- components/layout.blade.php -->
<html>
<body>
<header>{{ $header ?? 'Mi sitio' }}</header>
<main>{{ $slot }}</main>
<footer>{{ $footer ?? '© 2026' }}</footer>
</body>
</html>
blade
<!-- Uso -->
<x-layout>
<x-slot name="header">Mi cabecera personalizada</x-slot>
<h1>Contenido principal</h1>
<x-slot name="footer">Pie personalizado</x-slot>
</x-layout>
¿Ahora lo ves más claro? ¡Pregunta si necesitas más ejemplos! 😊
Laravel solo reconoce un único $slot por componente. El segundo $slot sobrescribiría al primero o causaría un error.
Para tener múltiples áreas, usamos slots con nombre (como vimos con sidebar).
💡 Ejemplo de múltiples slots en un mismo layout (si te interesa)
blade
<!-- components/layout.blade.php -->
<html>
<body>
<header>{{ $header ?? 'Mi sitio' }}</header>
<main>{{ $slot }}</main>
<footer>{{ $footer ?? '© 2026' }}</footer>
</body>
</html>
blade
<!-- Uso -->
<x-layout>
<x-slot name="header">Mi cabecera personalizada</x-slot>
<h1>Contenido principal</h1>
<x-slot name="footer">Pie personalizado</x-slot>
</x-layout>
¿Ahora lo ves más claro? ¡Pregunta si necesitas más ejemplos!
Definición de Layouts con Componentes de Blade en Laravel
Introducción
En este tutorial aprenderás a definir layouts en Laravel utilizando Componentes de Blade, una alternativa más moderna y flexible a las directivas tradicionales @yield y @section.
1. Estructura de Carpetas
Primero, creamos la carpeta para nuestros componentes:
text
resources/views/
└── components/
└── layouts/
Nota: La carpeta components es reconocida automáticamente por Laravel para los componentes de Blade.
2. Crear el Componente Layout
Creamos el archivo resources/views/components/layouts/app.blade.php:
blade
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="{{ $metaDescription ?? 'Descripción por defecto' }}">
<title>{{ $title ?? 'Título por defecto' }}</title>
<!-- Estilos -->
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
{{-- Navigation Component --}}
<x-layouts.navigation />
{{-- Main Content Slot --}}
{{ $slot }}
{{-- Footer --}}
<footer>
<p>© {{ date('Y') }} Mi Aplicación</p>
</footer>
</body>
</html>
Elementos clave:
{{ $slot }}: Es el slot principal, equivalente a @yield('content')
{{ $title ?? '...' }}: Propiedad con valor por defecto usando el operador ?? de PHP
{{-- Comentario --}}: Comentarios de Blade que no se renderizan en HTML
3. Usar el Componente en una Vista
En resources/views/welcome.blade.php:
Opción 1: Directiva @component
blade
@component('components.layouts.app')
<h1>¡Bienvenido!</h1>
<p>Este es el contenido principal.</p>
@endcomponent
Opción 2: Etiquetas x-* (Recomendada)
blade
<x-layouts.app>
<h1>¡Bienvenido!</h1>
<p>Este es el contenido principal.</p>
</x-layouts.app>
Ventaja: Sintaxis más limpia y similar a HTML.
4. Pasando Propiedades al Componente
Método 1: Atributos en la etiqueta
blade
<x-layouts.app
title="Mi Página de Inicio"
meta-description="Descripción personalizada"
>
<h1>¡Bienvenido!</h1>
</x-layouts.app>
Convención importante:
Atributos: Se escriben en kebab-case (meta-description)
Propiedades: Se acceden en camelCase ($metaDescription)
Método 2: Slots con nombre
Para contenido HTML complejo:
blade
<x-layouts.app>
<x-slot name="title">
<span class="text-primary">Título con HTML</span>
</x-slot>
<h1>Contenido principal</h1>
</x-layouts.app>
5. Evaluación de PHP en Atributos
Si necesitas evaluar expresiones PHP en atributos, usa el prefijo ::
blade
<!-- Esto NO evaluará PHP -->
<x-layouts.app zoom="1 + 2" />
<!-- Esto SÍ evaluará PHP -->
<x-layouts.app :zoom="1 + 2" />
En el componente:
blade
<div style="zoom: {{ $zoom }}"> <!-- Resultado: zoom: 3 --> </div>
6. Crear Componentes Anidados
Navegación (resources/views/components/layouts/navigation.blade.php):
blade
<nav>
<ul>
<li><a href="/">Inicio</a></li>
<li><a href="/about">Acerca de</a></li>
<li><a href="/blog">Blog</a></li>
<li><a href="/contact">Contacto</a></li>
</ul>
</nav>
Uso en el Layout:
blade
<!-- En app.blade.php -->
<body>
<x-layouts.navigation />
{{ $slot }}
</body>
7. Buenas Prácticas
Organización recomendada:
text
resources/views/
├── components/
│ ├── layouts/
│ │ ├── app.blade.php # Layout principal
│ │ └── guest.blade.php # Layout para invitados
│ ├── navigation.blade.php
│ └── footer.blade.php
├── pages/
│ ├── home.blade.php
│ ├── about.blade.php
│ └── contact.blade.php
└── welcome.blade.php
Actualizar todas las vistas:
blade
<!-- En about.blade.php, blog.blade.php, contact.blade.php -->
<x-layouts.app title="Página de Contacto">
<h1>Contacto</h1>
<!-- Contenido específico -->
</x-layouts.app>
8. Ventajas de Usar Componentes
9. Resumen y Recomendación Final
Pasos para migrar a componentes:
Crear la carpeta components/layouts/
Mover el layout a app.blade.php
Reemplazar @yield('content') por {{ $slot }}
Reemplazar @yield('title') por {{ $title ?? 'default' }}
Actualizar las vistas con <x-layouts.app>...</x-layouts.app>
Crear componentes para secciones reutilizables (navegación, footer)
¿Cuál elegir?
✅ Recomendado: Componentes de Blade (más modernos y flexibles)
⚠️ Alternativa: Directivas tradicionales (si prefieres sintaxis más familiar)
10. Ejemplo Práctico Completo
Vista welcome.blade.php:
blade
<x-layouts.app
title="Bienvenido a Mi App"
meta-description="Descripción personalizada para SEO"
>
<div class="hero">
<h1>¡Bienvenido!</h1>
<p>Contenido principal de la página de inicio.</p>
</div>
</x-layouts.app>
Componente Layout app.blade.php:
blade
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="{{ $metaDescription ?? 'Descripción por defecto' }}">
<title>{{ $title ?? config('app.name') }}</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
<x-layouts.navigation />
<main>
{{ $slot }}
</main>
<x-layouts.footer />
</body>
</html>
Conclusión
Los Componentes de Blade ofrecen una forma más limpia, modular y flexible de definir layouts en Laravel. Te permiten:
Pasar propiedades fácilmente
Crear componentes reutilizables
Mantener un código más organizado
Escribir sintaxis similar a HTML
¡Practica creando tus propios componentes y descubre todo su potencial!
Comentarios
Publicar un comentario