vue组件block名必须与文件名严格一致(如usercard.vue→user-card),bem命名失效会导致样式断链;动态类名需完整写出基础类与修饰符;穿透第三方组件须用bem容器限定作用域;modifier仅微调非布局属性,避免嵌套与冗余。

Block名必须和组件文件名完全一致
Vue组件名 UserCard.vue → Block名只能是 user-card,不是 card、user__card 或 UserCard。scoped不校验命名,但BEM语义失效后,后续所有嵌套(user-card__header、user-card--compact)都会失去模块归属感。
- 文件名大小写、空格、下划线都会破坏对应关系,比如
User_Card.vue就不该生成user-card - SCSS里用
&__header嵌套能防手误,但前提是根选择器已写对.user-card - 如果组件被重命名(如改叫
UserProfileCard.vue),所有类名前缀必须同步更新,否则样式断链
动态类名必须完整写出BEM全称
Vue模板中用 :class 绑定时,不能只写 isHover && 'user-card__item--hover',而漏掉基础类 user-card__item。scoped不会自动补全缺失的前缀,编译后生成的选择器是 .user-card__item--hover[data-v-xxx],但DOM上没有这个类,样式直接不生效。
- 正确写法:
:class="['user-card__item', isHover && 'user-card__item--hover']" - 错误写法:
:class="[isHover && 'user-card__item--hover']"(缺基础类)或:class="['item', isHover && 'item--hover']"(丢Block前缀) - 尤其注意
v-for生成的列表项,每个item都要独立声明完整BEM类名
穿透第三方组件必须用BEM容器限定范围
::v-deep(.el-button) 单独写在 <style scoped></style> 里毫无作用——因为 .el-button 元素不在当前组件DOM树内,也没带 data-v-xxx 属性。scoped穿透的前提是:外层必须有当前组件的BEM类名作为作用域锚点。
- 模板中包裹:
<div class="user-card__action"><el-button>编辑</el-button></div> - 样式中限定:
.user-card__action ::v-deep(.el-button) { height: 32px; } - 禁止写成
::v-deep(.el-button)或.user-card ::v-deep(.el-button)(太宽泛,可能影响其他组件) - Vue 3 中推荐用
:deep()替代::v-deep,语法更统一
Modifier只叠加,不重定义基础样式
user-card--compact 这类修饰符常被误用为“重写整个块”,比如在里面塞 font-size: 12px、border-radius: 0。这会让基础样式和状态逻辑耦合,一旦修改基础padding,就得同步改所有Modifier里的padding,维护成本陡增。
- Modifier应专注微调:仅用
padding、opacity、display、transform等不影响布局结构的属性 - 避免嵌套修饰符:
user-card__avatar--large--rotated应拆成user-card__avatar--large和user-card__avatar--rotated - 不要写
user-card--default—— 默认态就是没修饰符的状态,加了反而污染HTML和CSS
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











