# 样式作用域的实现原理

这里我们来剖析一下,单文件组件是如何实现样式私有化和样式穿透的

样式标签上带有 scoped 属性时:

  1. 当前组件的所有 HTML 元素(包括子组件的容器)都会携带一个属性,该属性是根据当前组件内容计算出的一个哈希值
  2. 当前组件的 CSS 规则集的最后会追加一个属性选择器,该属性选择器与 1 中的属性值匹配
  3. 使用深度选择器,深度选择器经过编译后被替换为 2 中的属性选择器,同时规则集最后不在追加属性选择器

通过 1 和 2 实现了样式私有化,通过 1,2,3 就实现了样式穿透。


<template>
  <div class="parent">
    <div class="example">hi</div>
  </div>
</template>
<style scoped></style>

编译后

<div data-v-452d6c4c class="parent">
  <div data-v-452d6c4c class="example">hi</div>
</div>

给当前组件的 HTML 标签打上唯一标识


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

编译后

.example[data-v-452d6c4c] {
  color: red;
}

这样就实现了样式私有化


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

编译后

[data-v-452d6c4c] .example {
  color: red;
}

这样就实现了样式穿透

# 相关资料

组件作用域 CSS (opens new window)