# 作用域 CSS

当一个 <style> 标签具有 scoped 属性时,它的 CSS 将只应用于当前组件的元素。这类似于 Shadow DOM 中的样式封装。它有一些注意事项,但不需要任何 polyfills。它是通过使用 PostCSS 来转换以下内容实现的

<style scoped>
.example {
  color: red;
}
</style>

<template>
  <div class="example">hi</div>
</template>

转换为以下内容

<style>
.example[data-v-f3f3eg9] {
  color: red;
}
</style>

<template>
  <div class="example" data-v-f3f3eg9>hi</div>
</template>

# 混合本地和全局样式

您可以在同一个组件中包含作用域和非作用域样式

<style>
/* global styles */
</style>

<style scoped>
/* local styles */
</style>

# 子组件根元素

使用 scoped,父组件的样式不会泄漏到子组件中。但是,子组件的根节点将受到父组件的作用域 CSS 和子组件的作用域 CSS 的影响。这是为了让父组件能够为了布局目的而对子组件根元素进行样式设置。

# 深度选择器

如果您希望 scoped 样式中的选择器是“深度”的,即影响子组件,您可以使用 >>> 组合器

<style scoped>
.a >>> .b { /* ... */ }
</style>

以上将编译成

.a[data-v-f3f3eg9] .b { /* ... */ }

一些预处理器,例如 Sass,可能无法正确解析 >>>。在这些情况下,您可以使用 /deep/::v-deep 组合器代替 - 它们都是 >>> 的别名,并且工作方式完全相同。根据上面的示例,这两个表达式将编译成相同的输出

<style scoped>
.a::v-deep .b { /* ... */ }
</style>
<style scoped>
.a /deep/ .b { /* ... */ }
</style>

# 动态生成的内容

使用 v-html 创建的 DOM 内容不受作用域样式的影响,但您仍然可以使用深度选择器对其进行样式设置。

# 也要记住

  • 作用域样式并不能消除对类的需求。由于浏览器渲染各种 CSS 选择器的方式,p { color: red } 在作用域中(即与属性选择器组合时)会慢很多倍。如果您使用类或 ID 代替,例如在 .example { color: red } 中,那么您实际上消除了这种性能损失。

  • 在递归组件中小心使用后代选择器!对于具有选择器 .a .b 的 CSS 规则,如果匹配 .a 的元素包含一个递归子组件,那么该子组件中的所有 .b 将与该规则匹配。