定义带header/body/footer的卡片组件需将视图置于resources/views/components/card.blade.php,用{{ $slot }}接收主体,命名插槽如$header、$footer必须用@isset判断存在性,否则报undefined variable;冒号语法为唯一合法插槽传入方式,大小写敏感且不支持嵌套。

Blade 组件不是“写完就能用”的黑盒,插槽也不是自动兜底的魔法变量——漏掉 @isset 或写错 <footer></footer> 的冒号,页面直接报 Undefined variable: footer。
怎么定义一个带 header/body/footer 的卡片组件
组件视图必须放在 resources/views/components/card.blade.php,文件名决定调用标签为 <x-card></x-card>。默认插槽用 $slot 接收主体内容,命名插槽如 $header、$footer 不会自动声明,必须显式判断存在性。
-
$slot总是存在,但可能是空字符串,用@empty($slot)比!$slot更准 - 命名插槽变量(如
$header)只在用了对应<header></header>时才被注入,否则未定义 - 别写
{{ $header }},要写@isset($header){{ $header }}@endisset或{{ $header ?? '默认标题' }} - 如果 footer 区域是可选的,用
@isset包裹整个<div class="card-footer">...</div>,避免渲染空 div
为什么 <x-slot name="footer"></x-slot> 渲染失败
Laravel 7+ 已完全弃用 @slot 和 name="footer" 写法,只认冒号语法 <footer></footer>。写错就等于没传,组件内 $footer 仍是未定义状态。
- 错误写法:
<x-slot name="footer">...</x-slot>→ 视为普通 HTML 标签,不触发插槽注入 - 正确写法:
<footer>...</footer>,且组件内必须有@isset($footer)或{{ $footer ?? '' }} - 大小写敏感:
<footer></footer>不会匹配$footer - 不能嵌套:
<header><footer>...</footer></header>是非法结构,Blade 不支持插槽嵌套
组件里混用 $slot 和命名插槽要注意什么
默认插槽和命名插槽共存没问题,但它们的渲染逻辑完全不同:$slot 是“所有未命名内容”,命名插槽是“按名提取的独立片段”。顺序、位置、是否提供都不影响匹配,但漏渲染就会丢内容。
- 外部写了
<header></header>但组件里没输出$header→ 内容静默丢失,无警告 - 外部没传
<footer></footer>,但组件里写了{{ $footer }}→ 直接报Undefined variable -
$slot会包含所有未被<xxx></xxx>捕获的内容,包括纯文本、换行、HTML 标签 - 想过滤掉空白或仅渲染非空内容?用
@if ($slot->isNotEmpty()){{ $slot }}@endif($slot是Illuminate\View\ComponentSlot实例)
修改组件后页面没变化?别忘了清缓存
Blade 编译后的 PHP 文件会被缓存,默认不随源文件实时更新。改了 card.blade.php 却看不到效果,大概率是缓存没清。
- 开发时执行:
php artisan view:clear - 如果用了 OPcache(常见于生产环境),还需执行:
php artisan opcache:clear - 注意:修改布局文件(如
layouts/app.blade.php)也要清缓存,它不走组件路径但同样被编译缓存 - 本地开发可临时关掉缓存:
APP_DEBUG=true+php artisan config:clear,但不要在生产环境这么干
最常被忽略的点是:命名插槽变量没有“默认初始化”这回事,Laravel 不会帮你设 $header = null;它要么存在,要么根本不存在。所以 @isset 不是防御性编程,而是必要操作。











