CSS Modules在Vue中通过构建时将类名重命名为唯一哈希(如components_Button__btn___aBc2d)实现局部作用域,需用声明、模板中通过$style.btn绑定,禁用scoped,嵌套须避免后代选择器,全局穿透用:global()。

在 Vue 单文件组件中使用 CSS Modules,核心是让每个类名自动变成唯一、带哈希的标识,从而天然避免跨组件类名冲突。它不依赖命名约定,也不靠属性选择器伪装,而是构建时重命名——只要配置和写法对,.button 就不会和另一个 .button 打架。
启用 module 属性即可开启模块化
只需在 <style></style> 标签上添加 module 属性:
-
<style module></style>:默认处理 CSS,无需额外配置(Vite 和 Vue CLI 均开箱支持) -
<style lang="scss" module></style>:用 Sass/SCSS 时必须显式声明lang,否则 loader 不识别,样式会退化为全局 - 不能同时写
scoped和module,二者机制冲突,只保留module
模板中通过 $style 绑定类名
模块化后,类名不再直接可用,必须通过组件实例的 $style 对象访问:
Element Plus Vue3 桌面组件库。在开发 Vue 3.x 页面时调用,使用 Element Plus 组件(如 el-button、el-input、el-form、el-table 等)。
<div :class="$style.container"></div><button :class="[$style.btn, $style.primary]">点击</button>- 伪类可直接写在样式里:
.btn:hover { background: #333; },编译后仍保持局部作用域
嵌套与组合要避开后代选择器
CSS Modules 不支持 .container .item 这类写法,因为两个类会被分别哈希,选择器无法匹配:
立即学习“前端免费学习笔记(深入)”;
- ❌ 错误:
.container .item { color: red; } - ✅ 正确:用
:is()或直接写同级类:.container-item { color: red; } - ✅ 复用其他模块类:用
composes(仅限同为.module.css的文件) - ✅ 需要穿透到全局时,用
:global(.third-party-class),但仅限对接外部库等必要场景
确保哈希唯一性:路径必须参与生成
类名重复往往不是偶然,而是哈希规则太宽松。默认配置可能忽略目录层级,导致 components/Button.module.css 和 pages/Button.module.css 中的 .btn 编译出相同哈希:
- Webpack 项目:在
css-loader的modules.localIdentName中设为[path][name]__[local]___[hash:base64:5] - Vite 项目:默认支持
.module.css,但若用.module.scss,务必确认已安装sass并启用对应 loader - 验证是否生效:打开浏览器开发者工具,看真实 DOM 的
class属性值 —— 应含路径片段(如components_Button__btn___aBc2d),而非纯btn__12345

















