在 vue 单文件组件中启用 css modules,只需在 标签上添加 module 属性,如 或 ;vue cli 和 vite 默认支持,但使用预处理器时需安装对应 loader(如 sass、less),且不可混用 scoped 与 module。

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










