@class 是 Laravel 9.2+ 内置语法糖,安全拼接条件类名,键必须为字符串字面量,值为布尔表达式,动态类名需先校验再注入。

Blade 中 @class 指令怎么写才不翻车
直接说结论:@class 是 Laravel 9.2+ 内置的语法糖,用来安全拼接条件类名,比手写三元或 implode 更简洁、更防空值。但它不是万能的,用错结构会报错或渲染出空字符串。
常见错误现象:@class(['btn', 'btn-primary' => $isActive, 'disabled' => !$enabled]) 看起来没问题,但如果 $isActive 是 null 或未定义变量,Laravel 不会报错但可能漏掉类名;更隐蔽的是,键名必须是字符串字面量(不能是变量),否则 PHP 解析失败。
-
@class接收一个数组,键为类名(字符串),值为布尔表达式 - 值为
true/1/ 非空字符串时,该类名生效;false/null/0/ 空字符串时跳过 - 键不能是变量(比如
[$dynamicClass => true]会报ParseError),只能是字面量或常量 - 数组里可以混用固定类名(无值)和条件类名(有键值对),顺序即渲染顺序
Laravel 8 及以下版本没有 @class 怎么办
别硬套——低版本 Blade 不识别这个指令,直接写会报 Undefined directive @class。得换兼容写法,核心是避免手动拼接字符串导致 XSS 或空格混乱。
推荐用 Arr::toCssClasses() 辅助函数(Laravel 7+ 自带),它和 @class 行为一致,且兼容所有版本:
@php
use Illuminate\Support\Arr;
@endphp
<div class="{{ Arr::toCssClasses([
'btn',
'btn-primary' => $isActive,
'disabled' => !$enabled
]) }}">
注意:不要用 join(' ', [...]) 手动拼,容易漏空格、多空格,也过滤不了 falsy 值;也不要自己写三元嵌套,可读性差还易错。
和 @if + class 属性拼接比,差在哪
有人图省事写:<div class="btn @if($isActive) btn-primary @endif @unless($enabled) disabled @endunless>。逻辑没错,但问题明显:
- 模板膨胀快,5 个条件就难维护
- 空格控制靠人肉,一不小心多空格或断行就出样式 bug
- 无法静态分析类名来源,IDE 和工具链(如 Tailwind CSS IntelliSense)基本失效
- 性能上差异极小,但可读性和协作成本高得多
而 @class 或 Arr::toCssClasses() 把类名逻辑收敛到一处,结构清晰,也方便后续加日志、监控或统一处理(比如自动前缀、主题切换)。
动态类名(比如来自数据库或配置)怎么安全加进去
这是最容易踩坑的地方:类名本身不确定,又想走 @class 流程。记住一条铁律——@class 的数组键必须是已知字符串,不能是运行时变量。
正确做法是先过滤、再合并:
@php
$allowedClasses = ['primary', 'success', 'warning', 'danger'];
$userClass = in_array($type, $allowedClasses) ? "alert-{$type}" : null;
@endphp
<div @class([
'alert',
$userClass,
'alert-sm' => $small,
])>
关键点:
- 动态生成的类名先校验合法性(防注入、防无效类),再赋值给变量
- 变量直接放在数组里当「固定项」用(无键),
@class会原样输出非空字符串 - 别试图写
@class([$userClass => true])—— 这会让 PHP 尝试把变量当数组键,报错
复杂场景下,宁可拆成两步:先构造干净数组,再传给 @class 或 Arr::toCssClasses()。类名逻辑越靠近数据层,模板越干净,也越不容易漏掉空值或 XSS 过滤。">


















