全局样式必须通过nuxt.config.ts的css数组配置,如css: ['~/assets/scss/bem.scss'];@import拼凑会导致作用域混乱、构建异常与热更新失效,且bem需配合@at-root扁平化类名及@nuxtjs/style-resources注入变量mixin。

全局样式入口必须用 css 配置,不能靠 @import 拼凑
直接在组件里 @import BEM 样式文件会导致作用域混乱、构建时无法提取公共 CSS、热更新失效。Nuxt 的 css 数组才是唯一可靠的全局注入点。
错误做法:@import '@/assets/scss/bem.scss' 写在某个页面或布局组件里;正确做法是在 nuxt.config.ts 中统一声明:
export default defineNuxtConfig({
css: ['~/assets/scss/bem.scss']
})
注意:如果同时存在 bem.css 和 bem.scss,Nuxt 默认优先加载 .css(扩展名匹配顺序为 ['css', 'pcss', 'postcss', 'styl', 'stylus', 'scss', 'sass', 'less']),所以务必删掉同名 .css 或显式写全扩展名。
bem.scss 文件里必须用 @at-root 保证类名扁平化
BEM 要求所有类名是独立的单层选择器,比如 .search-form__input,而不是 .search-form .search-form__input。但 SCSS 嵌套默认会生成后代选择器,不加控制就破坏 BEM 边界。
实操建议:
- 用
@mixin b($block)定义 block 根类,内部用&获取当前选择器 - 定义 element 时必须包裹
@at-root,否则&__input编译出来是.search-form .search-form__input - 禁止嵌套
&__input { &__icon {} }—— 这会产出.search-form__input .search-form__input__icon,违反 BEM 元素不可嵌套原则
示例片段:
@mixin b($block) {
$B: #{$namespace + '-' + $block};
.#{$B} {
@content;
}
}
.search-form {
@include b('search-form');
&__input {
@at-root .#{$namespace}-search-form__input {
padding: 8px;
}
}
}
JS 中动态拼接 BEM 类名极易出错,优先用 classnames 库
手写 className={`search-form__input ${isError ? 'search-form__input--error' : ''}`} 容易漏空格、拼错 modifier 名、状态组合爆炸(如 search-form__input--error--disabled 是非法写法)。
更安全的做法:
- 安装
npm install classnames - 在组件中统一用
classNames()管理 BEM 类名 - modifier 必须和 block/element 绑定,不单独存在:允许
search-form__input--error,禁止input--error
Vue 示例:
<script setup>
import classNames from 'classnames'
const props = defineProps({ isError: Boolean, isDisabled: Boolean })
const inputClass = classNames(
'search-form__input',
{ 'search-form__input--error': props.isError },
{ 'search-form__input--disabled': props.isDisabled }
)
</script><template><input :class="inputClass"></template>
BEM 变量和 mixin 必须通过 @nuxtjs/style-resources 注入,而非重复 @import
每个 SCSS 文件都 @import 一遍变量或 mixin,不仅冗余,还会导致重复定义警告、构建体积膨胀、变量覆盖顺序不可控。
正确路径:
- 安装
yarn add -D @nuxtjs/style-resources - 在
nuxt.config.ts中配置styleResources - 把命名空间
$namespace: 'xm'、BEM mixin(b/e/m)统一放在assets/scss/bem-utils.scss - 确保所有组件内 SCSS 都能直接用
@include b('button'),无需手动 import
容易踩的坑:如果 styleResources 没配对扩展名(比如写成 scss: ['./assets/scss/vars'] 却没加 .scss),Nuxt 就不会加载它,变量报错但无明确提示。
@at-root 和 styleResources 的配合,缺一不可。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











