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?

Blade clásico

Componentes

@yield('title')

Propiedad $title pasada como atributo

@section('sidebar') + @show

Slot con nombre sidebar + condicional en el layout

@yield('content')

Slot principal $slot

@extends('layouts.app')

<x-layout> con atributos y slots

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

Concepto en React

Concepto en Blade

Componente funcional

Componente de Blade (archivo .blade.php)

props

Atributos del componente (@props o variables)

children

{{ $slot }} (slot principal)

props que reciben JSX

Slots con nombre (<x-slot name="...">)

Componente de clase

Componente con clase PHP (app/View/Components/MiComponente.php)


🎯 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>&copy; {{ date('Y') }} Mi Aplicación</p>

    </footer>

</body>

</html>

Elementos clave:

  1. {{ $slot }}: Es el slot principal, equivalente a @yield('content')

  2. {{ $title ?? '...' }}: Propiedad con valor por defecto usando el operador ?? de PHP

  3. {{-- 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

Característica

Directivas Tradicionales

Componentes Blade

Sintaxis

@extends, @yield, @section

<x-* />, {{ $slot }}

Legibilidad

Menos intuitiva

Más similar a HTML

Propiedades

No soportadas nativamente

Fáciles de pasar y acceder

Reutilización

Limitada

Alta (componentes anidados)

Prefijo PHP

No en atributos

Usando : en atributos


9. Resumen y Recomendación Final

Pasos para migrar a componentes:

  1. Crear la carpeta components/layouts/

  2. Mover el layout a app.blade.php

  3. Reemplazar @yield('content') por {{ $slot }}

  4. Reemplazar @yield('title') por {{ $title ?? 'default' }}

  5. Actualizar las vistas con <x-layouts.app>...</x-layouts.app>

  6. 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

Entradas más populares de este blog

02 -Rutas en Laravel

01-04-convencion nombres

3-Rutas