摘要
在Vue项目中,尤其是在使用组件化
开发时,我们某些时候需要对组件内部的某些样式优化,但Vue
的样式封装特性
(scoped)会阻止外部样式
直接作用于组件内部。为了应对这一挑战,Vue社区
引入了深度选择器
(也称为穿透选择器
或阴影穿透选择器
),让我们能够跨越组件
的封装边界
,对内部元素进行样式定制
。
各深度选择器的区别
一、>>>
>>>
是CSS
原生中的深度选择器
语法,用于穿透样式封装。
-
**兼容性:**仅在某些特定环境(如
Webpack
的css-loader
配置中)和原生CSS中有效,Vue单文件组件中通常需要特定配置才能使用。 -
**注意:**在
Vue
单文件组件中,我们通常会搭配css预处理器
使用。但Sass
之类的预处理器
无法正确解析>>>
,所以不推荐使用>>>
,可以使用/deep/
或::v-deep
操作符取而代之,两者都是>>>
的别名,同样可以正常工作。
<style scoped>
.parent >>> .child {
/* 样式规则 */
}
</style>
二、/deep/
/deep/
曾经是CSS
中实际提出的新增功能,但之后被删除,所以不建议使用。
-
**兼容性:**支持
CSS预处理器
(如Sass
、Less
)和CSS
原生样式。 -
**注意:**在
Vue3
中,/deep/
不再被官方直接支持,虽然一些构建工具或库可能仍然兼容,但不推荐使用,使用后编译时控制台会输出警告信息。
/deep/ usage as a combinator has been deprecated. Use :deep() instead.
表示/deep/
是一个废弃的特性,请使用:deep()
替代。
<style scoped>
.parent /deep/ .child {
/* 样式规则 */
}
</style>
三、::v-deep
::v-deep是/deep/
的别名深度选择器
。
-
**兼容性:**支持
Vue2
,但在Vue3
中不推荐使用。 -
**注意:**在
Vue3
中,::v-deep
也不再被官方直接支持,虽然一些构建工具或库可能仍然兼容,但不推荐使用,使用后编译时控制台会输出警告信息。
::v-deep usage as a combinator has been deprecated. Use :deep() instead.
表示::v-deep
是一个废弃的特性,请使用:deep()
替代。
<style scoped>
.parent::v-deep .child {
/* 样式规则 */
}
</style>
四、::v-deep()
::v-deep()
是深度选择器
从Vue2
向Vue3
演化过程中的一个过渡性组合器。
- 用法:支持
Vue3
,但在编译时被视为已弃用并会引发警告。
<style scoped>
.parent ::v-deep(.child) {
/* 样式规则 */
}
</style>
五、:deep()
:deep()
是Vue3
官方推荐的深度选择器
,不建议使用>>>
和/deep/
以及::v-deep
包括::v-deep()
。
<style scoped>
.parent :deep(.child) {
/* 样式规则 */
}
</style>
演变过程
最初我们支持>>>
组合器,以使选择器“更深入”。但是,由于这不是官方的CSS组合器,因此某些CSS预处理器
(如SASS
)在解析它时会遇到问题。
我们后来改用了/deep/
,它曾经是CSS
中实际提出的新增功能(甚至在Chrome
中原生支持
),但后来被删除了。这给一些用户带来了困惑,因为他们担心/deep/
在Vue SFC
中使用会导致他们的代码在已删除该功能的浏览器中不受支持。但是,就像>>>
一样,/deep/
它仅被Vue
的SFC
编译器用作编译时提示来重写选择器,并在最终的CSS
中被删除。
为了避免因删除组合器而产生的混淆/deep/
,我们引入了另一个自定义组合器,::v-deep
这次更明确地表明这是一个特定于Vue
的扩展,并使用伪元素
语法,以便任何预处理器
都应该能够解析它。
出于兼容性原因,当前Vue2 SFC
编译器仍支持深度组合器的先前版本,这又会让用户感到困惑。在v3中,我们不再支持>>>
和/deep/
。
当我们在为v3开发新的SFC
编译器时,我们注意到CSS伪元素
实际上在语义上不是组合器。伪元素接受参数更符合惯用的CSS
,因此我们也以::v-deep()
这种方式进行工作。目前仍支持将作为组合器的::v-deep
用法,但它被视为已弃用并会引发警告。
>>> → /deep/ → ::v-deep → ::v-deep() → :deep()
结论
- 在Vue2中使用
::v-deep
; - 在Vue3中使用
:deep()
; /deep/
需要与特定浏览器版本搭配使用,不推荐使用- 部分CSS预处理器对
>>>
支持不佳,在不使用CSS预处理器时可使用,否则不推荐使用