Laravel 10 插槽语法未变但变量访问需显式声明,命名插槽须用 $slot->header 访问,默认插槽需判空处理,属性传递支持原生绑定但有保留字等限制,插槽存在性判断改用 $slot->has()。

命名插槽语法本身没变,但变量访问方式变了
Laravel 10 并没有修改 <x-slot name="header"></x-slot> 的写法,真正变化的是组件模板里怎么读取它。Laravel 9 允许你直接用 $header,而 Laravel 10 要求显式声明为插槽变量——否则会报 Undefined variable $header。
原因在于 Laravel 10 的 Blade 编译器强化了作用域隔离:命名插槽不再自动注入为同名变量,必须通过 $slots->get('header') 或更推荐的 {{ $slot->header }}(需配合组件定义中的 <slot name="header"></slot>)。
- 旧写法(Laravel 9 可用,10 报错):
{{ $header }} - 新写法(Laravel 10 必须):
{{ $slot->header ?? '' }}或{{ $slots->get('header', '') }} - 组件定义仍保持一致:
<slot name="header"></slot>,不是<slot name="header"></slot>标签本身变了
默认插槽的空值处理在 Laravel 10 更严格
以前写 {{ $slot }} 就完事,Laravel 10 下如果父级没传内容,$slot 不再是空字符串而是 Illuminate\Support\HtmlString 实例,且内部内容为 null —— 直接 echo 会触发 “Trying to get property 'value' of non-object” 类错误。
这不是 bug,是类型安全增强:Blade 现在把未填充的默认插槽当作“未定义”,而不是隐式转为空字符串。
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
- 安全写法(兼容 9 和 10):
{{ $slot ?? '' }}或{{ $slot->toHtml() ?? '' }} - 别再依赖
empty($slot)判断,改用$slot->isNotEmpty() - 如果你用
@isset($slot),Laravel 10 里它始终为 true(因为 $slot 总是对象),得换成@if($slot->isNotEmpty())
插槽属性传递在 Laravel 10 支持原生绑定,但有坑
Laravel 10 原生支持在 <x-slot></x-slot> 上直接传属性,比如 <x-slot name="header" :level="2"></x-slot>,然后在组件里用 {{ $slot->header->level }} 访问。听起来很爽,但实际容易踩三个坑:
- 属性名不能是 PHP 保留字(如
:class、:for),否则编译失败,得写成:class-name再在组件里转义 - 传数组或对象时,Laravel 10 默认只序列化基础类型,复杂结构会丢失方法和动态属性,建议用
json_encode()手动处理 -
:level="2"这种写法在 Laravel 9 完全不识别,会当成普通 HTML 属性透传,升级后务必检查所有带冒号的 slot 标签
组件内插槽判断逻辑从 @isset 变成 $slot->has
以前常用 @isset($footer) 判断命名插槽是否存在,Laravel 10 中这个变量根本不会被创建,所以 @isset 永远返回 false。正确方式是调用插槽管理器方法。
- 错误写法:
@isset($footer) ... @endisset - 正确写法:
@if($slot->has('footer')) ... @endif - 注意:这个
$slot是组件内注入的Illuminate\View\Compilers\Concerns\CompilesSlots实例,不是旧版那个松散变量 - 如果你用了
@props(['title' => ''])配合插槽,要小心两者优先级:插槽内容永远覆盖 props 默认值,哪怕 props 显式传了空字符串
最易被忽略的是插槽变量的“延迟初始化”行为:Laravel 10 不会在组件实例化时立刻解析所有插槽,而是首次访问 $slot->xxx 时才编译。这意味着你在 __construct() 或 mount() 里试图读取插槽内容会得到 null——得挪到 render() 或 Blade 模板里再用。

















