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 属于“最后手段”。