blade组件嵌套子内容不渲染的最常见原因是父组件模板中遗漏{{ $slot }},laravel不会自动透传内容,必须显式声明;每层包装组件(如container、form)都需包含且仅包含一处{{ $slot }},命名插槽变量名须与完全一致,大小写敏感。

Blade 组件嵌套时子内容不渲染
最常见现象是写了一堆 <x-form><x-input></x-input></x-form>,但页面只显示 <form></form> 标签,里面空空如也。根本原因不是语法错,而是父组件模板里漏了 {{ $slot }} —— Laravel 不会自动透传内容,必须显式声明。
实操建议:
- 逐层检查每个包装组件(比如
container.blade.php、card.blade.php、form.blade.php)是否都包含且仅包含一处{{ $slot }} - 别写成
{{ $slot() }}(这是旧版写法,Laravel 7+ 已失效) - 如果组件支持具名插槽(如
{{ $footer }}),默认主内容仍需靠{{ $slot }}接收,不能省略 - 用
@isset($slot){{ $slot }}@endisset可防空值报错,但非必需;更推荐直接{{ $slot }},因为未传内容时它就是空字符串
命名插槽内容被静默丢弃
写了 <x-card><header>Title</header><p>body</p></x-card>,但 header 不见了。问题通常出在两处:组件内没定义 $header 变量,或模板里没写 {{ $header }}。
实操建议:
- 命名插槽变量名必须与
<xxx></xxx>中的xxx完全一致(大小写敏感,不支持中划线自动转驼峰) - 组件视图中要显式输出,例如
{{ $header ?? '' }}或@if(filled($header)){{ $header }}@endif - 别混用语法:
<x-slot name="header"></x-slot>是旧写法,Laravel 7+ 要求用冒号语法<header></header> - 组件顶部用
@props(['header' => ''])可设默认值,避免未传时出错
嵌套层级深导致插槽变量作用域混乱
三层以上嵌套(如 <x-layout><x-card><x-form><x-input></x-input></x-form></x-card></x-layout>)后,某一层的 $slot 突然变 null 或内容错位。这不是 Laravel 的 bug,而是变量被覆盖或插槽未正确定义。
实操建议:
- 每一层组件都独立处理自己的
$slot,不要在组件逻辑里重新赋值$slot = ... - 避免在组件 PHP 类中手动修改
$slot属性(如$this->slot = ...),它由框架注入,只读 - 调试时可在任意组件视图中加
{{ gettype($slot) }} / {{ $slot ? 'not empty' : 'empty' }}快速确认是否接收到内容 - 如果某层组件需要“转发”插槽(比如 wrapper 组件只是加个 div),就原样输出
{{ $slot }},别做任何加工
Vue 风格写法误用导致解析失败
把 Vue 的 <template></template> 或 <slot name="footer"></slot> 直接抄到 Blade 组件里,结果报 Undefined variable: slot 或整个组件不渲染。Blade 和 Vue 插槽机制完全不兼容,语法不能混用。
实操建议:
- Laravel Blade 只认
<xxx></xxx>和{{ $xxx }},不识别<slot></slot>、<template></template>或v-slot - 不要在 Blade 组件里写 Vue 指令,除非你明确在前端用 Vue 渲染该区域(此时 Blade 只负责输出初始 HTML 字符串)
- 混淆常发生在使用 Inertia.js 项目中——注意区分服务端 Blade 渲染和客户端 Vue 渲染的边界
{{ $slot }},或者命名插槽变量名多了一个空格、少了一个字母。











