
Blade class 组件需定义继承 Illuminate\View\Component 的 PHP 类并实现 render() 方法,类须置于 app/View/Components/ 下且通过 artisan 命令生成;匿名组件则为 resources/views/components/ 下的纯 Blade 文件,通过 @props 声明属性,无需 PHP 类。
Blade class 组件不是直接写在视图里就能用的,它要求你先创建一个继承 Illuminate\View\Component 的 PHP 类,并在其中定义 render() 方法。Laravel 不会自动扫描视图目录下的 PHP 文件——类必须放在 app/View/Components/ 下,且需通过 php artisan make:component Alert 命令生成(否则命名空间、目录结构或自动发现容易出错)。
常见错误是把 class 组件当成普通模板直接 @include,结果报错 Class "App\View\Components\Alert" not found。正确做法是:运行命令生成类 → 在 render() 中返回 view('components.alert') → 然后在 Blade 中用 调用。
参数传递靠构造函数和 public 属性,例如:
class Alert extends Component
{
public string $type;
public string $message;
public function __construct(string $type = 'info', string $message = '')
{
$this->type = $type;
$this->message = $message;
}
public function render()
{
return view('components.alert');
}}
注意:构造函数参数不能是可选类型(如 ?string),否则 Laravel 无法解析依赖;$message 默认空字符串是安全的,但 null 会导致绑定失败。
Blade 匿名组件:零 PHP 类,直接复用视图文件
匿名组件本质就是一个带 @props 声明的 Blade 文件,无需 PHP 类、无需注册、不走服务容器。它适合轻量、无逻辑、纯展示型复用,比如按钮、卡片外壳、表单字段包装器。
使用前提是:文件必须放在 resources/views/components/ 目录下(如 resources/views/components/card.blade.php),且文件名决定标签名(card.blade.php → )。路径层级不影响调用,但不能嵌套子目录(components/ui/card.blade.php 不会被识别)。
@props 必须写在文件顶部,且只能出现一次;它接收传入的属性并自动转为变量:
@props(['title' => '', 'border' => true])
merge(['class' => 'p-4 rounded']) }}>
@if($title)
{{ $title }}
@endif
{{ $slot }}
调用时:内容区 。注意:$attributes 是默认注入的,用于透传未声明的 HTML 属性(如 id、data-* );$slot 是组件标签内的内容。
class vs 匿名组件:关键差异在哪
二者根本区别不在语法,而在执行时机和能力边界:
Request、Auth)、数据库查询、复杂条件判断;匿名组件只做变量替换,无法调用服务或执行业务逻辑@props 没有类型检查,传错参数(如传数组给期望字符串的 $title)可能只在运行时报 Notice 或渲染异常public $foo 暴露属性供模板访问,也可定义方法(如 public function cssClasses());匿名组件只能靠 @props 和内联逻辑无论是 class 还是匿名组件,$slot 和 $attributes 都不是“自动可用”的魔法变量——它们必须显式出现在模板中,且位置决定最终 HTML 结构。漏写 {{ $slot }} 就等于丢掉所有子内容;漏写 {{ $attributes }} 就等于丢掉外部传入的 class、id 等属性。
常见陷阱:
$attributes->merge([...]) 会覆盖同名属性(如外部传了 class="btn",而 merge(['class' => 'btn-primary']) 会完全替换,不是追加);要用 class="{{ $attributes->get('class', '') }} btn-primary" 手动拼接$slot 是 Illu
minate\Support\HtmlString 实例,不能直接用 isset($slot) 判断是否有内容,得用 !$slot->isEmpty() 或 strlen($slot) > 0
... )只在 class 组件中稳定支持;匿名组件不支持具名 slot,强行用会静默失效