vue组件block名必须与.vue文件名严格一致,如usercard.vue对应user-card;scss嵌套仅允许&--modifier和&__element模式;动态类名需完整声明前缀;穿透样式须用bem容器限定。

Block 名必须和 .vue 文件名完全对齐
Vue 组件的 Block 名不是语义选出来的,而是文件名的强制映射。UserCard.vue → Block 名只能是 user-card,不是 card、user__card 或 UserCard。工具链(如 stylelint-selector-bem-pattern、VS Code 类名跳转、postcss-bem)全靠这个映射工作。
常见翻车点:
-
SearchBar.vue写成searchbar或search-bar-component→ DevTools 里搜search-bar__input找不到定义 -
OrderSummaryItem.vue缩写为order-item→ 多个组件共用order-item,scoped 无法区分归属 - 模板中出现孤立类名,比如只写
__header或card__header→ scoped 不会自动补前缀,样式直接失效
SCSS 嵌套必须防非法选择器生成
& 是字符串拼接工具,不是 BEM 语法校验器。一不留神就产出违反规范的选择器,比如 .user-card--compact__header(修饰符不能直接修饰元素)。
安全写法只有一种模式:&--modifier &__element。
- ✅ 正确:
.user-card { &--compact &__header { padding: 6px; } }→ 编译为.user-card--compact .user-card__header - ❌ 错误:
.user-card { &--compact { &__header { } } }→ 编译为.user-card--compact__header - ❌ 错误:
.user-card { &__header { &--large { } } }→.user-card__header--large合法,但&--large &--focused会变成.user-card__header--large--focused,必须拆成两个 class
动态类名必须完整声明,别依赖 scoped 自动补全
scoped 不解析字符串拼接逻辑,它只给模板中显式写出的类名加 data-v-xxx 属性。手写 :class="['user-card__item', isHover && 'user-card__item--hover']" 没问题,但漏掉 user-card__ 前缀就彻底失效。

