直接用 Sass + 自定义 @mixin 即可实现 BEM,无需额外插件;Vite 内置 Sass 支持,只需安装 sass 依赖并正确配置 bem.scss 混入,注意 @at-root 和命名规范。

直接用 sass + 自定义 @mixin 就能跑起来,不用装额外插件或框架 —— BEM 本质是命名规范和 SCSS 工具链配合的问题,不是构建工具问题。
安装 sass 并确认 Vite 已支持
Vite 默认已内置 sass 支持(基于 dart-sass),只需确保项目里装了 sass 依赖:
-
npm install -D sass(node-sass已废弃,别用) - 检查
vite.config.ts中无需额外配置 —— Vite 会自动识别.scss文件并调用sass编译 - 如果 VS Code 报红
@mixin或变量,确认已安装官方Sass扩展(by Bradley Ayers),非SCSS插件
创建 bem.scss 并导出标准 BEM mixins
在 src/styles/bem.scss 中写入最小可用的三段式混入(block / element / modifier),不带命名空间也行,但建议加:
$namespace: 'xc' !default;
$block-sel: '-' !default;
$elem-sel: '__' !default;
$mod-sel: '--' !default;
@mixin b($block) {
$B: #{$namespace + $block-sel + $block};
.#{$B} {
@content;
}
}
@mixine($el) {
$selector: &;
@at-root {
#{$selector + $elem-sel + $el} {
@content;
}
}
}
@mixin m($mod) {
$selector: &;
@at-root {
#{$selector + $mod-sel + $mod} {
@content;
}
}
}
-
@at-root是关键,它让生成的.xc-panel__header不嵌套在父选择器下 - 不要用
@mixin e拼错成@mixin e(少个n),VS Code 里会报Unknown at rule - 若项目需多命名空间(如
admin-、report-),把$namespace提到单独的_vars.scss统一管理
在组件中正确使用 BEM mixins
Vue/React 组件内写 SCSS 时,必须满足两个条件才能让样式生效:
- 样式块需声明
lang="scss"(不是lang="css") -
@include b()必须作为最外层容器选择器,内部再嵌@include e()或@include m() - 错误示例:
{ @include b('card') }写在普通 CSS 规则里 ——@include只能在规则体内或顶层使用
正确写法:
<style lang="scss">
@import '@/styles/bem.scss';
@include b(card) {
padding: 16px;
@include e(header) {
font-weight: bold;
}
@include m(expanded) {
max-height: 500px;
}
}
</style>
避免 scoped 样式破坏 BEM 作用域
Vue 的 会给 class 加数据属性哈希(如 data-v-xxx),导致 .xc-card__header 类名被隔离,无法被全局逻辑或第三方库(如 ECharts 自定义 tooltip)匹配。
- 纯视觉类(颜色、间距、圆角等)可放
scoped;结构类(__header、__body)建议放全局 - 若坚持用
scoped,BEM 类名仍生效,但动态 JS 注入的 class(如 WebSocket 更新后加的xc-card--loading)可能因哈希不一致而无样式 - React 用户注意:CSS Modules 默认开启局部作用域,要用
className={styles['xc-card__header']}显式引用,不能直接写字符串
BEM 的坑不在写法,而在“谁负责解析 class 字符串”——Vite 不管这个,它只管编译 SCSS;真正决定哪些 class 被生成、哪些被 Tree-shaking 的,是你在 @include 里写的字面量是否被静态分析到。所以别在 mixin 调用里拼接变量名,比如 @include b(#{$type}),这会导致编译时无法确定最终类名,结果就是样式丢失且无任何提示。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











