slot 是可执行的 blade 片段而非值,本质为闭包,延迟执行并继承父级作用域变量;支持 blade 语法与嵌套组件,命名插槽自动驼峰转换,漏写 {{$slot}} 则内容丢失,不可与属性传值混用或替代。

Slot 是内容片段,普通变量是标量或数组值;传的是“可执行的 Blade 片段”,不是“值”本身。
Slot 本质是闭包,不是变量
Blade 编译器会把 @slot 或 <x-slot></x-slot> 内容包装成闭包,延迟到组件渲染时才执行。这意味着:
- 插槽内容能访问父级作用域里的变量(比如循环中的
$user),普通变量传值做不到这点 - 插槽里可以写
@if、@foreach、甚至嵌套其他组件,而title="xxx"这种属性只能传字符串或简单表达式 - 如果组件模板里漏写了
{{$slot}}或没定义对应命名插槽变量(如{{$header}}),内容就彻底丢失——不会报错,但也不渲染
命名插槽变量名由 name 属性自动转换
你写 <x-slot name="card-footer"></x-slot>,Laravel 会把它映射为变量 $cardFooter(驼峰命名),不是 $card_footer 或 $cardFooter 拼错就会是 undefined:
- 合法:
<x-slot name="main-content"></x-slot>→ 可在组件中用{{$mainContent}} - 非法:
<x-slot name="main_content"></x-slot>→$main_content不会被自动创建,需手动用@isset($attributes['name'])处理 - 不推荐混用:同一个组件里既用
{{$header}}又用@slot('header'),逻辑容易混乱
默认插槽和属性传值不能互相替代
比如你想做一个按钮组件:<x-button type="primary">提交</x-button>,这里 “提交” 是默认插槽,type="primary" 是属性:
- 插槽内容支持 HTML 标签、换行、多段文字;属性值只是字符串,
label="<strong>提交</strong>"不会解析为加粗文本 - 属性适合控制样式、行为(
disabled、size);插槽适合承载语义化内容(图标+文字、带链接的按钮文字) - 如果误把本该用插槽的内容塞进属性(如
content="<p>一段说明</p>"),Blade 不会转义也不会渲染 HTML,只会原样输出字符串
最常被忽略的一点:插槽内容在组件内部是“动态上下文”,它能感知外层 @foreach 的当前项、@auth 状态,而属性传值是静态快照——这点决定了你在封装表单字段、列表项、权限敏感操作组件时,必须用插槽,不能只靠变量传值。











