Vue 3 中 CSS Modules 的使用
FreeGuideOnline
最新
2026-07-06
vue
欢迎使用 CSS Modules
这是一个局部作用域的段落。
渲染后的 HTML 类名会变成类似 `_container_abc123` 的形式,确保唯一性。
## 自定义注入名称
`module` 属性可以接收一个自定义名称,这样样式对象就会注入到对应的名称下,而不是 `$style`。
```vue
<template>
<div :class="styles.container">
<span :class="styles.highlight">高亮文本</span>
</div>
</template>
<style module="styles">
.container { padding: 10px; }
.highlight { background-color: yellow; }
</style>
在组合式 API(<script setup>)中使用
在 <script setup> 语法中,无法直接使用 $style,需要通过 useCssModule() 函数获取样式对象。
<script setup>
import { useCssModule } from 'vue'
// 获取默认的 $style 对象
const $style = useCssModule()
// 如果使用了自定义名称
const styles = useCssModule('styles')
</script>
<template>
<div :class="$style.card">
<div :class="styles.footer">底部区域</div>
</div>
</template>
<style module>
.card { border: 1px solid #eee; border-radius: 8px; }
</style>
<style module="styles">
.footer { padding: 12px; background: #f9f9f9; }
</style>
动态绑定与组合类名
利用 JavaScript 模板字符串或数组语法,可以轻松组合多个模块类名,或者根据条件动态切换。
<template>
<button :class="[
$style.button,
isPrimary ? $style.primary : $style.secondary,
disabled ? $style.disabled : ''
]">
点我
</button>
</template>
<script setup>
import { ref } from 'vue'
const isPrimary = ref(true)
const disabled = ref(false)
</script>
<style module>
.button {
padding: 10px 20px;
border: none;
cursor: pointer;
}
.primary { background: #42b883; color: white; }
.secondary { background: #eee; color: #333; }
.disabled { opacity: 0.5; pointer-events: none; }
</style>
如何定义全局样式?
CSS Modules 默认将所有选择器局部化,但你可以使用 :global() 伪类来声明一个全局作用域的样式。
<style module>
.container {
/* 局部类 */
background: white;
}
.container :global(.global-class) {
/* .global-class 不会被 hash 化,直接作用于全局 */
font-weight: bold;
}
:global(body) {
margin: 0;
}
</style>
从独立 CSS 文件导入 Modules
你可以将样式写在单独的 .module.css 文件(或 .module.scss 等预处理器文件)中,然后导入到组件使用。
styles/card.module.css:
.card {
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
padding: 16px;
}
.header {
font-size: 1.2rem;
margin-bottom: 12px;
}
组件中导入:
<script setup>
import cardStyles from './styles/card.module.css'
</script>
<template>
<div :class="cardStyles.card">
<div :class="cardStyles.header">独立模块化样式</div>
</div>
</template>
使用预处理器(SCSS/Less 等)
Vue 对 CSS Modules 与预处理器的结合做了完美支持,只需在 <style> 标签上同时指定 module 和 lang 属性即可。
<style module lang="scss">
$primary: #42b883;
.button {
background: $primary;
&:hover {
background: darken($primary, 10%);
}
&.disabled {
opacity: 0.5;
}
}
</style>
组合(Composition)与 composes 特性
CSS Modules 规范允许通过 composes 关键词从一个类继承样式,Vue 编译器同样支持该特性。
<template>
<div :class="$style.card">
<div :class="$style.header">标题</div>
</div>
</template>
<style module>
.baseCard {
border-radius: 12px;
overflow: hidden;
background: white;
}
.card {
composes: baseCard;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.header {
composes: baseCard from global; /* 假设 baseCard 定义在全局样式中 */
padding: 12px;
}
</style>