惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

aimingoo的专栏
aimingoo的专栏
Engineering at Meta
Engineering at Meta
有赞技术团队
有赞技术团队
博客园_首页
Apple Machine Learning Research
Apple Machine Learning Research
Vercel News
Vercel News
G
Google Developers Blog
Blog — PlanetScale
Blog — PlanetScale
IT之家
IT之家
MongoDB | Blog
MongoDB | Blog
Y
Y Combinator Blog
B
Blog
The GitHub Blog
The GitHub Blog
M
MIT News - Artificial intelligence
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Stack Overflow Blog
Stack Overflow Blog
C
Check Point Blog
Microsoft Azure Blog
Microsoft Azure Blog
D
DataBreaches.Net
I
InfoQ
Recent Announcements
Recent Announcements
阮一峰的网络日志
阮一峰的网络日志
腾讯CDC
H
Help Net Security

博客园 - 且行且思

Win11 家庭版 远程桌面连接-突然发生身份验证错误,(错误代码: 0x800706be) — 通过添加windows凭证解决 Cesium 加载 3dtiles ,实现球体旋转、模型定位 Tomcat服务自动关闭 , 定时检查并重启 用echarts打造会转的立体饼图 BaseMetas Fileview在线文件预览解决方案 ECharts GL | 3D 地图区域高度设置 物联网智慧平台 蚂蚁地理空间数据可视化 - 基于 WebGL 的开源大规模地理空间数据可视分析引擎。 主流开源JS地图框架选择 kk-anti-reptile 是适用于基于 spring-boot 开发的分布式系统的开源反爬虫接口防刷组件。 NProgress 给 Vue 路由切换加个 “假” 进度条提升用户体验 一个watch让页面卡成PPT? JAVA 对于class文件反编译,CFR 通常能产生最完整的代码。 用AI辅助设计登录页 免费白嫖Claude 4小技巧 Jmeter压测工具入门篇 性能工具之 JMeter 快速入门 高并发压力测试工具清单 Nginx 单机多实例负载均衡 IntelliJ IDEA 中 Shared Build Process Heap Size 的重要性与配置 微信小程序实现流式传输(打字机效果)
只会 !important 改 UI? Vue 深度选择器解法
且行且思 · 2025-11-06 · via 博客园 - 且行且思

一文吃透 Vue2 / Vue3 的 ::v-deep/deep/>>>:deep() 区别,结合 Element Plus 实战演示,顺便告诉你“为什么劝你别滥用”。

1. 为什么需要“深度选择器”?

在 .vue 文件里,只要给 <style> 加上 scoped 属性,Vue 就会自动为模板内的所有 DOM 节点打上一个哈希属性(如 data-v-7ba5bd90),并把样式选择器也后缀同一哈希,从而实现“样式隔离”。

编译前后对比:


/* 源码 */
.title { color: red; }

/* 编译结果 */
.title[data-v-7ba5bd90] { color: red; }

好处:父组件的样式不会泄漏到子组件。
副作用:父组件想改子组件内部样式也改不动了
于是“深度选择器”应运而生——它允许你在 scoped 中“穿透”这一层隔离。

2. 语法速查表(Vue2 vs Vue3)

写法Vue2 支持Vue3 支持官方态度备注
>>> 废弃 原生 CSS 语法,Sass 不识别
/deep/ 废弃 Sass/Scss 可用
::v-deep 兼容 任何预处理器通用
:deep() 推荐 Vue3 唯一官方推荐写法

结论:
Vue2 项目统一用 ::v-deep
Vue3 项目统一用 :deep(),别再写 /deep/ 或 >>> 了。

3. 最小可运行 DEMO(Vue3 + Vite)

下面用 Element Plus 的 el-button 做靶子,把按钮里的文字颜色改成渐变色。


<!-- DeepSelectorDemo.vue -->
<template>
  <section>
    <h3>3.1 默认样式</h3>
    <el-button>我是按钮</el-button>

    <h3>3.2 深度选择器覆盖后</h3>
    <el-button class="g-custom">我是按钮</el-button>
  </section>
</template>

<script setup>
/* 无需逻辑,纯样式演示 */
</script>

<style scoped>
/* 仅对第二个按钮生效 */
.g-custom :deep(span) {
  background: linear-gradient(45deg, #ff0066, #ffcc00);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
</style>

4. 编译结果揭秘

打开 DevTools → Elements → 选中按钮 → 观察 span 元素:


<span class="">
  我是按钮
</span>

注意:

  1. 1. span 本身没有data-v-xxx 属性;
  2. 2. 父元素 button.g-custom 有 data-v-7ba5bd90
  3. 3. 最终生效的 CSS 选择器是:

.g-custom[data-v-7ba5bd90] span { ... }

Vue 通过把哈希加在深度选择器左侧而非右侧,实现了“只穿透、不污染”。

5. 高频踩坑 5 连问

问题原因解法
1. :deep(.a .b) 不生效? 括弧里写完整后代选择器会被 Sass 解析异常 改成 :deep(.a) :deep(.b) 或 .a { :deep(.b) {} }
2. 嵌套 scoped 样式里写 :deep() 无效? 嵌套层级导致哈希插错位置 用 @at-root 把深度选择器提到根(仅限 Sass)
3. 全局样式文件里写 :deep() 报错? 深度选择器只能在 scoped 内使用 去掉 scoped 即可,本来就是全局
4. 小程序/uni-app 里不支持? 小程序无真实 DOM,哈希机制不同 用官方提供的 ::v-deep 或深度样式覆盖方案
5. 打包后样式丢失? 配置了 css.modules 导致选择器被哈希两次 关闭 css.modules 或改用 ::v-deep

6. 最佳实践口诀

  1. 1. 能不用就不用:先尝试子组件暴露 class / style / props 让父组件传值。
  2. 2. “就近”深度:深度选择器尽量贴近目标元素,减少副作用范围。
  3. 3. 一个组件一套深度:别把整站样式都写进一个 scoped 深度里,后期调试想哭。
  4. 4. 升级 Vue3 立刻全局替换 /deep/ → :deep(),一劳永逸。
  5. 5. 写 UI 库主题时,用官方提供的 theme 或 css var,深度选择器只是兜底。