为什么需要样式穿透
当我们创建私有组件时(组件样式标签添加scoped),引用了子组件或 UI 组件,你会发现在我们私有组件并不能直接修改其样式。遇到这种情况,一般有两种解决方式:一是添加全局样式(需要覆盖全局样式时);再者就是样式穿透了(组件样式)。
样式穿透的三种方式
以下三种方式在 Vue3 中均已弃用,详见 Vue3 组件样式变化。
- >>>:适用于- css、stylus
- /deep/:适用于- node-sass、less
- ::v-deep:适用于- dart-sass、node-sass、less、stylus
| 1 | <!-- >>> 用法 --> | 
Vue3 组件样式变化
根据 Vue 的 RFC 文件(意见征求稿)中,以上三种样式穿透方式都已被弃用,将用::v-deep() 简写 :deep() 替代。官方文件详情 => 私有样式改变 RFC。

文稿中大致意思是,最初使用的深度选择器是 >>> ,但某些 CSS 预编译器解析时存在问题,后来切换到 /deep/,曾经添加到 CSS 标准提议 中,后被放弃,为了避免混淆又引入了自定义的组合器 ::v-deep。为了兼容性,vue2 中才保留了其他两种。
在开发新的 vue3 SFC 编译器时,我们注意到 CSS 伪元素实际在语义上不是组合器,伪元素接受参数更符合惯用的 CSS,所以采用了 ::v-deep() 替换,简写 :deep()。
注:截止 2022 年 5 月 以上 3 种旧的深度选择器任能在 vue3 项目中使用,但会有警告提示信息;

另外 Vue3 中还添加了另外两个伪元素 ::v-slotted() 和 ::v-global()。总结如下:
- ::v-deep()简写- :deep():深度选择器(样式穿透);
- ::v-slotted()简写- :slotted():插槽选择器;- Vue3 默认情况下,作用域样式不会影响到 - <slot/>渲染出来的内容,因为它们被认为是父组件所持有并传递进来的。使用- :slotted()伪类以确切地将插槽内容作为选择器的目标。
- ::global()简写- :global():全局选择器;- 如果想让其中一个样式规则应用到全局,比起另外创建一个 - <style>,可以使用- :global()伪类来实现。
| 1 | <style scoped> | 




