bem命名本身不防scoped混乱,必须人工对齐block名、静态声明类名、限定穿透范围;usercard.vue的block名只能是user-card,类名须显式写出如user-card__avatar,动态类需完整声明,穿透须限定在.user-card__actions内。

BEM命名本身不防scoped混乱,必须靠人工对齐Block名+静态声明类名+限定穿透范围,否则scoped只会帮你“安全地污染”更多地方。
Block名必须与组件文件名完全一致
Vue的scoped只加data-v-xxx属性,它不管类名是否符合BEM——你写.card__header在UserCard.vue里,编译后是.card__header[data-v-xxx],但模板里根本没这个类,样式自然不生效。
-
UserCard.vue→ Block名只能是user-card,不是card、userCard或user-card-component -
SearchBar.vue→ 必须用search-bar,不能缩写为search或bar - 模板中所有类名必须显式以
user-card开头:user-card__avatar✅,__avatar❌,avatar❌
动态类名必须完整写出,不能拼接
Vue无法解析运行时拼接的字符串,scoped不会给'user-card--' + status这种表达式注入属性选择器,结果就是样式丢失。
分析 Vue 3 Composition API 使用情况——审计响应式模式、可组合函数设计、ref 与 reactive 的选择、计算属性、watcher 使用及组件……
- 正确写法:
:class="['user-card', { 'user-card--loading': isLoading }]"✅ - 错误写法:
:class="'user-card--' + status"❌(编译后user-card--loading没data-v-xxx) - 修饰符也得带完整前缀:
user-card--disabled✅,--disabled❌
穿透子组件必须用BEM容器限定范围
直接::deep(.el-button)会匹配整个页面所有el-button,绕过BEM语义且破坏隔离。真正可控的方式是把第三方节点纳入你的BEM结构。
- 推荐:
<el-button class="user-card__submit-btn"></el-button>,再在scoped里写.user-card__submit-btn - 若必须穿透:
::deep(.user-card__actions .el-button)✅,::deep(.el-button)❌ -
Teleport内容已脱离组件作用域,必须用全局BEM类名,且Block名需全局唯一(如modal不能在多个弹窗组件里重复)
最容易被忽略的是:SCSS嵌套中&只是语法糖,不校验BEM合法性。比如.user-card { &--compact { &__header {} } }会生成.user-card--compact__header,这违反BEM规范——修饰符不能直接修饰元素。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










