结论:用$slot接默认内容,命名插槽用x-slot传入并配合@isset或??空值判断,否则会报undefined variable错误;卡片组件中header/body/footer需分别用@isset($header)、{{ $slot }}、@isset($footer)安全渲染。

直接说结论:用 $slot 接默认内容,用 x-slot 标签传命名插槽,别漏掉 @isset 或空值判断——否则渲染时会报 Undefined variable: header 这类错误。
如何定义一个支持 header/body/footer 的卡片组件
Blade 组件本质是 PHP 视图文件,不是类;插槽靠变量注入,不是 props 传递。关键点在于:默认插槽用 $slot,命名插槽对应同名变量(如 $header),但这些变量不会自动声明,必须手动判断是否存在。
- 运行
php artisan make:component Card生成骨架 - 在
resources/views/components/card.blade.php中写结构,{{ $slot }}放主体,{{ $header ?? '' }}或@isset($header){{ $header }}@endisset处理可选区域 - 不要写
public $header;—— Blade 组件没有属性声明语法 - 如果 footer 是可选的,用
@isset($footer)包裹整块 DOM,比{{ $footer ?? '' }}更安全(避免空 div)
怎么在页面里正确传入 header 和 footer 内容
调用时不能直接写 <x-card header="标题" footer="底部"></x-card> —— Blade 组件不支持 HTML 属性传参(除非你手写构造函数并注册 props,但那是进阶用法,90% 场景不需要)。
- 默认插槽内容写在
<x-card>...</x-card>标签体内,不加任何标签 - 命名插槽必须用
<x-slot name="header">...</x-slot>,name 值要和组件内变量名完全一致(区分大小写) - 多个
x-slot可以混排,顺序无关,Blade 会按 name 匹配注入 - 别把
x-slot写成slot或@slot—— Laravel 10+ 只认x-slot标签语法
为什么有时候 $header 渲染为空或报错
根本原因:命名插槽变量不是“可选参数”,而是“未定义就访问”。Laravel 不会为你初始化 $header、$footer 等变量,它们只在你用了对应 x-slot 时才存在。
- 错误写法:
{{ $header }}→ 没传header插槽时直接报Undefined variable - 正确写法:
{{ $header ?? '默认标题' }}或@isset($header){{ $header }}@endisset - 如果组件里用了
@props(['title']),那是 props 机制,和插槽无关,别混用 - 调试技巧:在组件开头加
{{ dump(get_defined_vars()) }}看当前有哪些插槽变量被注入
要不要给插槽加默认内容或 fallback
可以,但得手动实现。Blade 本身不提供 slot="header" fallback="..." 这种语法。
- 想让
header有默认值?写{{ $header ?? '信息卡片' }} - 想让整个
footer区域有条件显示?用@isset($footer)<div class="card-footer">{{ $footer }}</div>@endisset - 别依赖
@slot('header') @endslot写法 —— 这是旧版 Laravel 的写法,Laravel 10+ 已弃用,只支持x-slot - 复杂 fallback(比如渲染一段默认按钮组)建议抽成子组件,而不是硬塞在主组件里
最容易被忽略的是变量存在性检查 —— 很多人只记得给 $slot 加判断,却忘了 $header 和 $footer 同样需要防御性写法。插槽不是“参数”,是“条件注入的内容”,这点不厘清,组件一换场景就崩。











