跳到主要内容

scoped 样式穿透

面试速答(30 秒版 TL;DR)

  • scoped 的原理:编译时给当前组件 DOM 打上类似 data-v-xxxx 的属性选择器,使样式只作用于本组件。
  • “样式穿透”的需求:需要影响子组件内部 DOM(例如第三方组件库的内部结构)。
  • Vue 3 推荐:::v-deep(...)(或 :deep(...))做深度选择器;老写法 >>>/deep/ 多已弃用。

scoped 的工作方式(理解就够)

组件:

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

编译后大致会变成:

  • DOM:<button class="btn" data-v-xxxx>
  • CSS:.btn[data-v-xxxx]{ color:red }

所以默认情况下,样式不会“穿到”子组件内部。


穿透写法(Vue 3 常用)

<style scoped>
.wrapper :deep(.el-input__inner) {
border-radius: 12px;
}
</style>

要点:

  • :deep(...) 里面的选择器不再附加 data-v-xxxx 限制,因此能选中子组件内部元素。

常见坑

  • 穿透依赖子组件内部 DOM 结构,组件库升级可能导致 class 变化,样式失效。
  • 能用组件库提供的 theme/变量/props 就别 deep,deep 属于“最后手段”。