在 Vue 单文件组件中启用 CSS Modules,只需在 <style> 标签上添加 module 属性,如 <style module> 或 <style lang="scss" module>;Vue CLI 和 Vite 默认支持,但使用预处理器时需安装对应 loader(如 sass、less),且不可混用 scoped 与 module。

如何在 Vue 单文件组件中启用 module 属性
直接在 <style> 标签上加 module 属性即可启用 CSS Modules,无需额外配置(Vue CLI 和 Vite 默认支持)。不写 lang 时默认为 CSS;若用预处理器,需显式声明:<style lang="scss" module>。
常见错误现象:写了 module 却发现类名没哈希化、样式仍全局生效——大概率是漏了 lang 声明,且项目未配置对应 loader(比如用了 scss 却没装 sass 或 sass-loader)。
-
<style module>→ 纯 CSS,安全可用 -
<style lang="less" module>→ 需确保已安装less和less-loader - 不要混用
scoped和module:两者目的重叠,同时存在时scoped会被忽略
$style 对象的访问方式与限制
$style 是一个响应式计算属性,由 vue-loader 自动注入,只能在组件实例上下文中访问。它不是原始 CSS 模块对象,而是编译后映射的只读键值对(如 { title: "MyComponent_title__abc123" })。
容易踩的坑:
立即学习“前端免费学习笔记(深入)”;
- 在
setup()中直接访问this.$style会报错(this不存在)→ 改用useCssModule() -
useCssModule()必须在setup()或<script setup>内调用,否则返回空对象 - 若用了自定义注入名(如
<style module="classes">),必须传参调用useCssModule('classes')
示例:
<script setup>
import { useCssModule } from 'vue'
const classes = useCssModule()
// 或 const classes = useCssModule('classes')
</script>
动态绑定 $style 类名的几种写法
不能直接写 :class="$style.title" 当作字符串用——它本质是对象,需走对象语法或解构。最稳妥的是用计算属性或 useCssModule 返回值。
推荐组合方式:
- 静态 + 动态混合:
:class="[$style.title, mini ? $style.mini : '']" - 条件对象:
:class="{ [$style.title]: true, [$style.mini]: mini }" - 解构后使用(
<script setup>):const { title, mini } = useCssModule(),然后:class="[title, mini && mini]"
注意:$style 的 key 是原始类名(小驼峰或短横线均可),但构建后生成的 class 名含哈希,不可硬编码。
与全局类、第三方库样式的共存策略
CSS Modules 只处理 <style module> 内部的类,对外部 class(如 Bootstrap、Element Plus)完全无感。想混用必须手动拼接,不能依赖 composes 或自动注入。
关键点:
- 全局类写在
class属性里,模块类写在:class里,二者互不干扰 - 避免在
<style module>中用:global(.btn)覆盖第三方样式——这会破坏封装性,且易被后续更新覆盖 - 需要复用其他模块样式?用
composes(仅限同文件或@import进来的模块 CSS):.primary { composes: button from './base.module.css'; }
真正容易被忽略的是:CSS Modules 不解决 BEM 或语义化命名问题,它只做作用域隔离。类名是否可维护,仍取决于你写 .header 还是 .MyComponent_header。


















