导航
scoped 样式穿透,指的是:
在 scoped 样式作用范围内,主动让样式作用到子组件内部的 DOM
scoped 样式:
只能作用于「当前组件直接生成的 DOM」
❌ 不包括:
Parent.vue
└── Child.vue
└── <div class="inner">真实 DOM</div>
<template>
<div class="child">
<div class="inner">I am inner dom</div>
</div>
</template>
<template>
<Child />
</template>
<style scoped>
.inner {
color: red;
}
</style>
Vue 编译后发生了什么:
.inner[data-v-parent] {
color: red;
}
<div class="inner" data-v-child>
I am inner dom
</div>
.inner[data-v-parent]
↑
但 DOM 上是 data-v-child
➡️ scoped 的本质限制:属性不一致,选择器不匹配
我们可以把 scoped 理解为:
“我只管我自己模板里生成的 DOM”
<style scoped>
:deep(.inner) {
color: red;
}
</style>
[data-v-parent] .inner {
color: red;
}
<div data-v-parent>
<div data-v-child>
<div class="inner">I am inner dom</div>
</div>
</div>
[data-v-parent] .inner
↑ ↑
父组件根 任意后代
✔ 不再要求 .inner 自己携带 data-v-parent
| 情况 | 选择器 | 能否命中子组件 DOM |
|---|---|---|
| 普通 scoped | .inner[data-v-parent] | ❌ |
| 样式穿透 | [data-v-parent] .inner | ✅ |
<template>
<Child>
<div class="slot-inner">slot dom</div>
</Child>
</template>
<style scoped>
.slot-inner {
color: red;
}
</style>
<template>
<div class="wrapper">
<slot />
</div>
</template>
👉 会生效!
因为:
<div class="slot-inner" data-v-parent>
✔ scoped 是“按来源组件”,不是“按渲染位置”