laravel 7+ 统一使用 + 语法支持默认与命名插槽;$slot 自动注入且不可调用 $slot(),命名插槽需变量名完全匹配并手动渲染。

Blade 插槽(slot)和命名插槽(named slot)是 Laravel 组件化布局的核心机制,它们让组件具备内容可替换性,但容易混淆的是:Laravel 7+ 已弃用旧式 @slot 语法,统一使用 + 结构;用错语法会直接报错 undefined variable: slot 或渲染为空。
如何定义一个支持默认插槽的组件
在 resources/views/components/card.blade.php 中写:
{{ $header ?? 'Default Header' }} {{ $slot }}
注意:$slot 是自动注入的 IlluminateViewComponentSlot 实例,调用它会渲染传入的默认内容。不能写成 {{ $slot() }}(这是旧版写法,已失效),也不能漏掉 ?? 判断导致未传 $header 时报错。
如何在视图中使用默认插槽和命名插槽
调用组件时,用 标签包裹内容,默认内容进入 $slot;用 指定命名插槽(name 必须与组件内 $slotName 变量名或 @props 中定义一致):
This is the main content.
It goes into the default slot.
常见错误包括:
- 写成
—— 错,必须用冒号语法
- 组件内没定义
$footer或没在模板里写{{ $footer }}—— 命名插槽内容会被静默丢弃 - 在同一个组件中混用
$slot和$footer,但没给默认插槽内容 ——$slot会是空字符串,不是 NULL,需用@empty($slot)判断
如何支持多个命名插槽并设置默认值
命名插槽变量默认为 null,可在组件顶部用 @props 设置默认值:
@props(['header', 'footer' => null]) {{ $header }} {{ $slot }} @if($footer) {{ $footer }} @endif
这样即使调用时不传
,也不会报错。但要注意:$footer 是字符串,不是组件实例;如果想透传子组件(比如按钮组件),得用 {{ $footer }} 渲染,不能用
然后期望自动解析 —— Blade 不会二次编译插槽内容,除非你手动调用 $footer->tohtml()(不推荐)。
为什么命名插槽有时不生效?检查这三点
最常卡住的地方其实是路径和注册问题:
- 组件文件名必须小写中划线,如
app/View/Components/Card.php对应,而对应UserCard.php - 组件类必须继承
IlluminateViewComponent,且不能漏掉render()方法或 blade 路径返回 - 命名插槽名大小写敏感:
和
{{ $footer }}不匹配,必须完全一致
插槽机制本身不复杂,但 Laravel 的自动解析链(组件类 → 视图路径 → 插槽变量绑定 → 渲染时机)有一环断掉,就只会静默失败。建议先用最简 dd($slot, $footer) 确认变量是否注入成功,再往下调样式或逻辑。