Componentes Blade desde cero-super
Componentes Blade desde cero
Voy a explicarte los componentes Blade desde lo más básico, partiendo de las vistas normales, pasando por los layouts, y llegando a los componentes. Al final entenderás cómo se llama el componente, cómo se usa, y cómo se le meten datos.
Parte 1: La vista Blade normal (el punto de partida)
Una vista Blade es solo un archivo .blade.php con HTML y un poco de sintaxis especial.
resources/views/saludo.blade.php
<!DOCTYPE html>
<html>
<head>
<title>Saludo</title>
</head>
<body>
<h1>Hola, {{ $nombre }}</h1>
<p>Bienvenido a mi sitio</p>
</body>
</html>Aquí:
{{ $nombre }}→ variable que le pasa el controlador.La vista es autónoma: tiene su propio
<html>,<head>,<body>.
Problema: si tienes 20 vistas, repites el <html>, <head>, <body> en cada una. Ahí entran los layouts.
Parte 2: El layout clásico (evitar repetir el cascarón)
Un layout es una plantilla con huecos (@yield) que otras vistas rellenan.
resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html>
<head>
<title>@yield('title', 'Mi App')</title>
</head>
<body>
<header>Mi sitio web</header>
<main>
@yield('content') {{-- hueco principal --}}
</main>
<footer>© 2026</footer>
</body>
</html>Cómo se usa desde una vista:
resources/views/home.blade.php
@extends('layouts.app')
@section('title', 'Lista de tareas')
@section('content')
<h1>¡Bienvenido!</h1>
<ul>
<li>Tarea 1</li>
<li>Tarea 2</li>
</ul>
@endsectionCómo funciona:
@extends→ "usa este layout como cascarón".@section('title', ...)→ rellena el@yield('title').@section('content') ... @endsection→ rellena el@yield('content').
Idea clave: el layout tiene huecos (@yield) y la vista los llena (@section).
Parte 3: El componente (una pieza reutilizable con su propio hueco)
Un componente es como un layout mini, pero reutilizable en cualquier parte, no solo como cascarón de página.
3.1 ¿Cómo se llama el componente?
Aquí viene lo importante. El nombre del componente se deriva de la ruta del archivo. No hay que registrar nada manualmente en Laravel moderno.
| Archivo | Nombre al usarlo |
|---|---|
resources/views/components/alerta.blade.php | <x-alerta> |
resources/views/components/boton.blade.php | <x-boton> |
resources/views/components/card.blade.php | <x-card> |
resources/views/components/forms/input.blade.php | <x-forms.input> |
resources/views/components/ui/boton-primario.blade.php | <x-ui.boton-primario> |
Reglas del nombre:
Todo lo que está dentro de
components/se convierte en un componente.La carpeta se convierte en prefijo separado por punto:
forms/input→x-forms.input.Los guiones se mantienen:
boton-primario→x-ui.boton-primario.El prefijo
x-es obligatorio en el uso.
Así que el nombre del componente = ruta del archivo desde components/, con / → . y prefijo x-.
3.2 ¿Cómo se ve por dentro?
resources/views/components/alerta.blade.php
@props(['tipo' => 'info'])
<div class="alerta alerta-{{ $tipo }}">
{{ $slot }}
</div>Tres piezas:
@props([...])→ declara qué atributos acepta el componente y sus valores por defecto.$tipo→ variable que viene de los atributos (tipo="exito").$slot→ todo el contenido que va entre las etiquetas del componente.
3.3 ¿Cómo se usa?
resources/views/home.blade.php
@extends('layouts.app')
@section('title', 'Lista de tareas')
@section('content')
<h1>¡Bienvenido!</h1>
<x-alerta tipo="exito">
Todo salió bien
</x-alerta>
<ul>
<li>Tarea 1</li>
<li>Tarea 2</li>
</ul>
@endsectionAquí:
<x-alerta tipo="exito">→ usa el componentealerta.tipo="exito"→ atributo que llega a$tipo.Todo salió bien→ contenido que llega a$slot.
3.4 ¿Cómo se meten datos? Dos canales distintos
| Canal | Cómo se escribe | Cómo se lee dentro | Para qué |
|---|---|---|---|
| Atributos | <x-alerta tipo="exito"> | @props(['tipo' => 'info']) → $tipo | Configuración (tipo, color, id…) |
| Slot | Contenido entre etiquetas | {{ $slot }} | Contenido principal (texto, HTML…) |
Regla mental:
$slot= "lo que va dentro de las etiquetas". Es contenido.@props/$tipo= "lo que va en los atributos". Es configuración.
Parte 4: Ejemplo completo paso a paso (lo que pasa cuando Laravel renderiza)
Toma esto:
<x-alerta tipo="exito">
Todo salió bien
</x-alerta>Paso 1: Laravel ve <x-alerta> y busca resources/views/components/alerta.blade.php.
Paso 2: Procesa @props(['tipo' => 'info']):
Como le pasaste
tipo="exito",$tipo = "exito".Si no hubieras pasado
tipo, sería$tipo = "info".
Paso 3: Procesa {{ $slot }}:
$slot = "Todo salió bien".
Paso 4: Renderiza:
<div class="alerta alerta-exito">
Todo salió bien
</div>Paso 5: Ese HTML reemplaza al <x-alerta> dentro del @section('content') de home.blade.php.
Paso 6: El @section('content') llena el @yield('content') del layout.
Paso 7: HTML final:
<!DOCTYPE html>
<html>
<head>
<title>Lista de tareas</title>
</head>
<body>
<header>Mi sitio web</header>
<main>
<h1>¡Bienvenido!</h1>
<div class="alerta alerta-exito">
Todo salió bien
</div>
<ul>
<li>Tarea 1</li>
<li>Tarea 2</li>
</ul>
</main>
<footer>© 2026</footer>
</body>
</html>Parte 5: Los tres mecanismos comparados
| Mecanismo | Archivo | Hueco | Cómo se llena |
|---|---|---|---|
| Vista normal | saludo.blade.php | {{ $variable }} | Controlador pasa variables |
| Layout clásico | layouts/app.blade.php | @yield('content') | @section('content') |
| Componente | components/alerta.blade.php | {{ $slot }} + $props | Contenido entre etiquetas + atributos |
Conviven sin problema. En el ejemplo final:
El layout usa
@yield.El componente usa
$slot.La vista
home.blade.phpllena el@yieldcon@section, y dentro de ese@sectionusa<x-alerta>para llenar el$slot.
Parte 6: Cómo se llama el componente — resumen definitivo
El nombre del componente se forma así:
resources/views/components/alerta.blade.php
↓
<x-alerta> (en cualquier vista)
resources/views/components/ui/boton.blade.php
↓
<x-ui.boton>
resources/views/components/forms/input.blade.php
↓
<x-forms.input>Fórmula:
Quita
resources/views/components/y.blade.php.Cambia
/por..Añade el prefijo
x-.
No hay que registrar nada. Laravel lo descubre automáticamente (componentes anónimos).
Parte 7: Tres formas de pasar datos al componente
a) Atributo simple → $props
<x-alerta tipo="exito">...</x-alerta>@props(['tipo' => 'info'])
<div class="alerta-{{ $tipo }}">{{ $slot }}</div>b) Contenido → $slot
<x-alerta>Todo salió bien</x-alerta>{{ $slot }} {{-- Todo salió bien --}}c) Slots con nombre (varios huecos)
<x-card titulo="Mi tarjeta">
Contenido principal
<x-slot:footer>
Pie de la tarjeta
</x-slot:footer>
</x-card>@props(['titulo'])
<div class="card">
<h2>{{ $titulo }}</h2>
<div>{{ $slot }}</div>
<footer>{{ $footer }}</footer>
</div>Parte 8: Chuleta final
{{-- 1. Definir el componente: resources/views/components/alerta.blade.php --}}
@props(['tipo' => 'info']) {{-- atributos con default --}}
<div class="alerta alerta-{{ $tipo }}">
{{ $slot }} {{-- contenido entre etiquetas --}}
</div>
{{-- 2. Usarlo en cualquier vista --}}
<x-alerta tipo="exito">
Todo salió bien
</x-alerta>
{{-- 3. Resultado --}}
<div class="alerta alerta-exito">
Todo salió bien
</div>Lo esencial:
Nombre del componente = ruta del archivo desde
components/con/→.y prefijox-.@props= atributos (configuración).$slot= contenido (lo que va entre las etiquetas).@yield= hueco de layout clásico (se llena con@section).$slot= hueco de componente (se llena con el contenido entre etiquetas).Son dos mecanismos distintos que pueden convivir en la misma vista
Comentarios
Publicar un comentario