1. 什么是样式穿透?
样式穿透是在使用 Vue 组件时,为了修改子组件或第三方组件的样式而使用的一种特殊语法。当我们使用 scoped
样式时,由于样式被限制在当前组件内,要修改子组件的样式就需要使用样式穿透。
2. 为什么需要样式穿透?
2.1 Scoped 样式的局限性
<!-- 父组件 -->
<template>
<div class="parent">
<child-component class="child" />
</div>
</template>
<style scoped>
.child {
/* 这里的样式只会影响到子组件的根元素 */
/* 无法影响到子组件内部的元素 */
color: red;
}
</style>
2.2 常见使用场景
- 修改第三方组件样式
- 修改子组件内部元素样式
- 覆盖默认主题样式
3. 不同版本的样式穿透语法
3.1 Vue2 中的样式穿透
<!-- 1. 使用 >>> 操作符 -->
<style scoped>
.parent >>> .child {
color: red;
}
</style>
<!-- 2. 使用 /deep/ -->
<style scoped>
.parent /deep/ .child {
color: red;
}
</style>
<!-- 3. 使用 ::v-deep -->
<style scoped>
.parent ::v-deep .child {
color: red;
}
</style>
3.2 Vue3 中的样式穿透
<!-- 推荐写法 -->
<style scoped>
/* 方式1:直接作用于子元素 */
:deep(.child) {
color: red;
}
/* 方式2:从父元素开始 */
.parent :deep(.child) {
color: red;
}
</style>
4. 在不同预处理器中的使用
4.1 SCSS/SASS 中的使用
<style lang="scss" scoped>
/* Vue2 中 */
.parent {
/deep/ .child {
color: red;
}
::v-deep .child {
color: red;
}
}
/* Vue3 中 */
.parent {
:deep(.child) {
color: red;
}
}
</style>
4.2 LESS 中的使用
<style lang="less" scoped>
/* Vue2 中 */
.parent {
/deep/ .child {
color: red;
}
}
/* Vue3 中 */
.parent {
:deep(.child) {
color: red;
}
}
</style>
5. 实际应用示例
5.1 修改第三方组件样式
<!-- 修改 Element Plus 组件样式 -->
<template>
<div class="custom-form">
<el-form>
<el-input v-model="value" />
</el-form>
</div>
</template>
<style lang="scss" scoped>
.custom-form {
/* Vue3 写法 */
:deep(.el-input) {
.el-input__inner {
border-radius: 8px;
border-color: #409EFF;
}
}
}
</style>
5.2 修改多层级嵌套组件
<style scoped>
.parent {
/* 多层级选择器 */
:deep(.level-1) {
.level-2 {
.level-3 {
color: blue;
}
}
}
}
</style>
6. 其他深度选择器
6.1 插槽选择器(:slotted)
<style scoped>
/* 修改插槽内容的样式 */
:slotted(.slot-class) {
color: red;
}
</style>
6.2 全局选择器(:global)
<style scoped>
/* 添加全局样式 */
:global(.global-class) {
color: blue;
}
</style>
7. 版本迁移建议
如果你正在将项目从 Vue2 迁移到 Vue3,建议:
- 将所有
>>>
替换为:deep()
- 将所有
/deep/
替换为:deep()
- 将所有
::v-deep
替换为:deep()
8. 总结
样式穿透是 Vue 中解决组件样式隔离问题的重要工具:
使用场景:
- 修改第三方组件样式
- 修改子组件内部样式
- 处理插槽内容样式
语法选择:
- Vue3 中统一使用
:deep()
- 避免使用已废弃的语法
- 根据预处理器选择合适的写法
- Vue3 中统一使用
通过合理使用样式穿透,我们可以更好地控制组件样式,同时保持代码的可维护性和性能。