Blade 组件需在AppServiceProvider::boot()中用Blade::component()显式注册,类名带完整命名空间;匿名组件无需注册但不支持传参解构;推荐使用<x-xxx>语法而非@component,因其支持属性绑定、插槽和动态组件名;$attributes需用{{$attributes}}输出,$slot默认转义,输出HTML需用{!! $slot !!}。

Blade 组件怎么注册才能被识别
Laravel 不会自动扫描 app/View/Components 下的类,必须显式注册——哪怕你用了 Artisan 命令生成,也得手动加进 AppServiceProvider::boot() 里。漏掉这步,@component 或 <x-xxx> 都会报错:Class 'xxx' not found 或 Component [xxx] not found。
- 在
app/Providers/AppServiceProvider.php的boot()方法中调用Blade::component() - 类名要带完整命名空间,比如
App\View\Components\Alert - 别名可选,但建议保持和文件名一致,避免混淆:
Blade::component('alert', Alert::class) - 如果用匿名组件(即无 PHP 类、只有 Blade 文件),路径必须是
resources/views/components/alert.blade.php,且无需注册——但不支持传参解构或构造函数逻辑
用 <x-xxx> 还是 @component
两者都能用,但行为差异明显:<x-xxx> 是 Laravel 7+ 推荐语法,支持属性绑定、作用域插槽、动态组件名;@component 是旧写法,仅支持简单传参,且无法使用 $attributes 或 $slot。
-
<x-alert type="danger">出错了</x-alert>→ 属性自动转为组件类的 public 属性或构造参数 -
@component('components.alert', ['type' => 'danger'])<?php echo $slot ?? '' ?>@endcomponent→ 手动传数组,不支持插槽解构 - 动态组件名只在
<x-{$name}>中有效,@component不支持变量名 - 如果组件需要接收 HTML 内容(比如按钮包裹文字),必须用
<x-xxx>+$slot,@component里得靠echo $slot ?? ''手动输出,且没类型提示
$attributes 和 $slot 怎么安全使用
这两个是 Blade 组件的核心变量,但直接 echo 或渲染容易出 XSS 或结构错乱。
-
$attributes是Illuminate\View\ComponentAttributeBag实例,不是普通数组,不能用array_merge;要用$attributes->merge([...])合并 class 或其他属性 - 渲染用户传入的
$slot时,默认已转义;如果真要输出 HTML,必须显式用{!! $slot !!},但得确保内容可信 - 想过滤 slot 内容?别自己 preg_replace,用
{{ $slot->toHtml() }}(需先use Illuminate\Support\HtmlString;)或封装成子组件处理 - 常见错误:在组件内写
<div {{ $attributes }}>{{ $slot }}</div>→ 报错,因为$attributes要用{{$attributes}}(双大括号)输出,不是花括号表达式
组件里怎么访问请求或认证状态
组件类本身不自动注入 Request 或 Auth,但可以像普通控制器一样通过构造函数依赖注入,或用辅助函数。
- 构造函数注入更清晰:
public function __construct(public Request $request, public bool $isLoggedIn = false) { ... } - 也可以在
render()方法里调用auth()->check()或request()->route('id'),但注意性能:每次渲染都触发,可能重复查 session 或路由 - 避免在组件里做重操作(如 DB 查询),它可能被多次调用;复杂逻辑应提前算好,通过属性传入
- 若组件需响应 dark mode 等前端状态,别在 PHP 层读 localStorage,而是用 props 传入
:dark="true"(配合 Alpine 或 Vue)
组件的边界容易模糊——它不是控制器,也不该替代布局。真正难的是判断“这段逻辑该放组件里,还是该由父模板传值决定”。这个分寸,调试几次 DOM 结构和 props 流向就清楚了。










