Blade插槽不自动继承父作用域,需显式控制类型和作用域;$slot为空或报“Undefined variable”因执行上下文不一致:纯HTML时为字符串,含Blade逻辑时为Closure须用$slot()执行;具名插槽需显式输出{{ $name }},判断内容应使用$slot->isNotEmpty()而非@isset。

Blade 插槽本身不自动继承父作用域,传复杂内容必须显式控制类型和作用域——否则 $slot 要么是空字符串,要么是 Closure 但无法访问你想要的变量。
为什么 $slot 有时渲染为空,有时报错 “Undefined variable”
根本原因是插槽内容的执行上下文不一致:
- 纯 HTML 或静态文本 →
$slot是字符串,直接{{ $slot }}就行 - 含 Blade 逻辑(如
@foreach、{{ $user->name }})→$slot是 Closure,必须用{{ $slot() }}才能执行 - 用了
scope: true但 Laravel 版本 $slot() 执行时仍拿不到父组件@props - 在具名插槽里写
{{ $slot }}却没声明@slot('name')→$slot是空 Closure,$slot->isNotEmpty()才能安全判断
@slot 传数组 vs scope: true:怎么选
两者互斥,不能混用;选哪个取决于你是否需要“动态绑定”:
- 传数组(推荐 Laravel 9+):
@slot('header', ['title' => '编辑', 'level' => 2])→ 插槽内直接用{{ $title }}、{{ $level }} - 单值简写:
@slot('footer', $user->name)→ 插槽内只能用{{ $slot }}(不是$footer) -
scope: true(Laravel 10.28+):@slot('actions', scope: true)→ 插槽内可直接访问父组件所有@props,比如{{ $row->id }},但不能访问调用方模板里的局部变量(如@for中的$i) - 混用会触发错误:
Cannot mix scoped and non-scoped slots
嵌套组件中 $slot 消失的真正原因
不是语法错,是中间某层组件漏写了 {{ $slot }}:
- 每层“容器型”组件(如
container、card、form)都必须在其 Blade 模板里显式输出{{ $slot }} - 缺了它,子内容就无处落脚,被静默丢弃 —— 即使
<x-container><x-form>...</x-form></x-container>写得再对也没用 - 具名插槽同理:如果组件定义了
@slot('sidebar'),但模板里没写{{ $sidebar }},那内容照样不渲染 - 检查路径没问题?先 grep 一下组件文件里有没有
{{ $slot }}或{{ $$name }}
判断插槽是否有内容,别用 @isset($slot)
@isset($slot) 永远为 true,因为哪怕没传内容,$slot 也是个空 Closure。正确方式只有两个:
-
{{ $slot->isNotEmpty() }}—— 安全、语义明确,适用于所有插槽类型 -
@if ($slot->count())—— 仅当插槽内容是 Collection 风格时可用,不通用 - 具名插槽如
$header,同样用{{ $header->isNotEmpty() }},不是@isset($header)
最易忽略的一点:作用域传递只发生在组件定义层,调用方模板里的变量(比如 @foreach ($items as $item) 中的 $item)永远进不了 scope: true 插槽——那是编译时隔离的,不是运行时闭包共享。











