单文件组件CSS功能--:样式穿透deep()

:Deep()深度选择器的作用

原理为将私有属性转到上一层

例子1

scoped作用:
1.给每一个DOM节点添加唯一的标签(如:data-v-a1012)
2.在css选择器末尾加上对应的属性选择器(如:.user[data-v-a1012],来私有化样式)
如果组件内包含其他组件,只会给其他组件的最外层标签加上当前组件的data属性

转义前

<style lang="scss" scoped>
.container{
  background: #fff;
  .ep-rate{
	background: black;
	.ep-rate__item{
	  background: red;
	}
  }
}
</style>

转义后

.container[data-v-7ba5bd90] { background: #fff; } 
.container .ep-rate[data-v-7ba5bd90] { background: black; } 
.container .ep-rate .ep-rate__item[data-v-7ba5bd90] { background: red; }

如果.ep-rate是子组件的根元素,那么想要直接进行样式修改是不成功的。
因为在使用了scoped的情况下,子组件会被添上与父节点不相同的唯一的标签。具体例子如下:

父组件:

<template>
  <div class="container">
	<ChildComponent />  <!-- 子组件的根元素是 .ep-rate -->
  </div>
</template>
<style lang="scss" scoped>
.container {
  .ep-rate {
	background: black;  /* 试图修改子组件的 .ep-rate */
  }
}
</style>

子组件:(ChildComponent.vue)

<template>
  <div class="ep-rate">  <!-- 子组件的根元素 -->
	<div class="ep-rate__item"></div>
  </div>
</template>

编译后:

父组件的样式会被编译为

.container[data-v-aaaaaa] .ep-rate[data-v-aaaaaa] {
  background: black;
}

子组件的根元素会带着自己的data-v

<div class="ep-rate" data-v-bbbbbb>  <!-- 注意:这里是 data-v-bbbbbb -->
  <div class="ep-rate__item" data-v-bbbbbb></div>
</div>

可以看到因为父组件和子组件带的data并不一样,所以父组件样式的写法并不会影响子组件。


下面使用深度选择器

将父组件样式修改为:

.container {
  :deep(.ep-rate) {
	background: black;
  }
}

编译后如下:

.container[data-v-aaaaaa] .ep-rate {
  background: black;
}

可以看到加了:deep之后,私有属性提升到了上一层,deep内的class都没有加私有属性。可以实现样式的修改。现在它可以匹配子组件的 .ep-rate(无论子组件的 data-v 是什么)。


例子2

如果是子组件的写法,子组件的最外层(根元素),会带上自己的data-v-bbbb(而不是父组件的data-v-aaaa)

示例

父组件

<template>
  <div class="parent">  <!-- 父组件的根元素,data-v-aaaaaa -->
	<Child></Child>     <!-- 子组件的根元素,data-v-bbbbbb -->
  </div>
</template>

<style scoped>
.parent {
  color: red;
}
.parent .child {
  background: blue;
}
</style>

子组件Child:

<template>
  <div class="child">  <!-- 子组件的根元素,data-v-bbbbbb -->
	<p>Child Content</p>
  </div>
</template>

DOM渲染效果:

<div class="parent" data-v-aaaaaa>
  <div class="child" data-v-bbbbbb>  <!-- 注意:这里是 data-v-bbbbbb -->
	<p>Child Content</p>
  </div>
</div>

通过:deep()穿透

.parent {
  :deep(.child) {
	background: blue;
  }
}

编译后:

.parent[data-v-aaaaaa] .child {
  background: blue;
}

:deep()移除了对.child[data-v-aaaaaa]限制,可以匹配子组件的.child

posted @ 2025-08-14 14:52  GoldWind  阅读(299)  评论(0)    收藏  举报