在 Vue.js 中,组件的 CSS 样式默认是全局生效的。但通常我们希望组件的样式只作用于当前组件,避免影响到其他组件,这就是所谓的 CSS 作用域(Scoped CSS)。Vue 提供了几种方法来实现 CSS 作用域。
单文件组件(Single File Components)
如果你使用的是 Vue 的单文件组件(`.vue` 文件),可以在 `<style>` 标签中使用 `scoped` 属性来实现样式的作用域限制:
<template>
<div>
<h1>这是一个标题</h1>
<p>这是一个段落。</p>
</div>
</template>
<script>
export default {
name: 'MyComponent'
}
</script>
<style scoped>
h1 {
color: red;
}
p {
color: blue;
}
</style>
在上面的例子中,`h1` 和 `p` 的样式只会应用到当前组件内的元素上,不会影响其他组件中的 `h1` 和 `p` 元素。
CSS Modules
CSS Modules 是一种自动为类名添加唯一前缀的方法,从而避免了全局冲突。在 Vue 中,你可以通过给 `<style>` 标签添加 `module` 属性来使用 CSS Modules:
<template>
<div>
<h1 class="title">这是一个标题</h1>
<p class="paragraph">这是一个段落。</p>
</div>
</template>
<script>
export default {
name: 'MyComponent'
}
</script>
<style module>
.title {
color: red;
}
.paragraph {
color: blue;
}
</style>
使用 CSS Modules 时,你需要在 JavaScript 中通过解构来使用样式:
export default {
name: 'MyComponent',
computed: {
classes() {
return {
title: this.$style.title,
paragraph: this.$style.paragraph
}
}
}
}
然后在模板中使用 `class` 绑定:
<template>
<div>
<h1 :class="classes.title">这是一个标题</h1>
<p :class="classes.paragraph">这是一个段落。</p>
</div>
</template>
深度选择器(Deep Selectors)
有时候,你可能需要对组件内部的深层嵌套元素应用样式,或者对子组件的根元素应用样式。在这种情况下,你可以使用深度选择器(`::v-deep`):
<style scoped>
::v-deep(.some-class) {
/* 样式规则 */
}
</style>
或者,如果你使用的是 Vue 3 和 SCSS/SASS,可以使用 `/deep/` 或 `::v-deep`:
<style lang="scss" scoped>
::v-deep {
.some-class {
/* 样式规则 */
}
}
</style>
请注意,深度选择器的使用应该谨慎,因为它可能会破坏组件封装的样式隔离。
注意事项
- 使用 `scoped` 时,样式只会应用到当前组件的 `<template>` 中的元素。
- `scoped` 和 `module` 不能同时使用。
- 在某些构建工具(如 webpack)中,CSS Modules 可能需要额外的配置。