不是css modules,仅提供属性选择器隔离;css modules需+:class="$style.xxx"绑定,二者机制不同、不可混用。

Vue单文件组件中启用
直接说结论:<style scoped></style>不是CSS Modules,它只是Vue提供的样式作用域隔离方案;而真正的CSS Modules需要显式开启modules属性,并配合class绑定语法使用。两者底层机制不同,混用会导致样式失效或类名无法解析。
常见错误是以为加了scoped就等于启用了CSS Modules——其实scoped靠的是属性选择器(如[data-v-f3f3eg9]),而CSS Modules靠的是构建时重命名+导出对象,必须通过:class或class动态绑定才能生效。
-
<style scoped></style>:无需修改模板,所有class自动加scope属性,但类名不被JS访问 -
<style module></style>:必须用:class="{ $style.xxx }"或:class="$style.xxx",否则样式不会应用 - 同时写
<style scoped module></style>是合法的,但scoped在此冗余,因为CSS Modules本身已保证局部性
在Vue 2/3中正确启用CSS Modules
关键在<style></style>标签的module属性,以及模板中如何消费生成的类名对象。Vue CLI和Vite都默认支持,无需额外配置。
示例(Vue 3 + Composition API):
<style module>
.red {
color: red;
}
.bold {
font-weight: bold;
}
</style><p><template><div :class="[$style.red, $style.bold]">Hello</div>
<!-- 或分开写 -->
<div :class="$style.red">Red only</div>
</template></p>
-
$style是Vue注入的响应式对象,键为原始类名,值为哈希后的真实类名(如red_1a2b3c) - 不支持
class="red"这种静态写法,那样会直接输出red,而不是哈希后的类名 - Vue 2中同样可用
$style,但需确保使用vue-loader@15.9+及以上版本
如何在<script setup>中解构$style并避免重复书写</script>
每次写$style.xxx太啰嗦,可以用const { red, bold } = $style解构,但要注意:解构后的变量不是响应式的,且不能在模板中直接当标识符用(Vue模板不识别解构变量)。
更实用的做法是用defineProps或computed封装:
<script setup>
import { computed } from 'vue'
const $style = useCssModule() // Vue 3.3+ 推荐方式
// 或直接用全局注入的 $style(Vue 3.2+ 默认可用)
<p>const classes = computed(() => ({
red: $style.red,
bold: $style.bold
}))
</script><p><template><div :class="classes">Hello</div>
</template></p>
-
useCssModule()只在<script setup></script>中可用,返回当前<style module></style>的对象 - 如果组件有多个
<style module></style>,可传参指定name,如useCssModule('common') - 解构
$style后赋值给ref或computed才能在模板中安全使用,否则可能触发“未定义”警告
与CSS预处理器(如Sass)联用时的注意事项
支持,但语法要匹配:CSS Modules对预处理器无侵入,只需在<style></style>上同时声明lang和module。
<style lang="scss" module>
.red {
color: red;
&.highlight {
background: yellow;
}
}
</style>
- Nested规则(如
&.highlight)会被正确编译,但生成的类名仍是模块化的(如red_1a2b3c highlight_4d5e6f) - 不能在
<style module></style>中使用@import引入外部CSS文件——那部分不会被模块化,类名不会重命名 - 若需复用变量或mixin,应改用
@use(Sass 1.32+)并确保它们定义在模块内或通过defineOptions({ style: { ... } })注入
CSS Modules真正难的不是启用,而是习惯放弃“全局class思维”。一旦开始用$style,你就得接受所有样式都要走JS路径,连最简单的class="btn"都要变成:class="$style.btn"——这点容易被忽略,直到你在控制台看到一堆没生效的原始类名。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











