上午在做一个弹窗el-dialog,需要展示导入的失败信息。需求如下:展示导入失败信息,失败行数超过10行展示滚动条,想了一下大概就是动态控制el-dialog滚动条样式。
好久没写样式穿透,没想到咋写都不生效,看了俩小时才写出来,记录一下。
我们的需求是给el-dialog加上滚动条样式,一般来说通过:deep(.el-dialog)即可修改dialog的样式,但由于滚动条样式是需要动态控制的,所以通过动态class+样式穿透的方法实现。
1. :class动态控制样式
用v-bind:class
传给class
一个对象,动态切换class
是否存在。
<div :class="{ scrollDialog: scrollVisible }">
<el-dialog
v-model="dialogVisible"
:width="props.width"
@close="closeDialog"
>
</el-dialog>
</div>
// 控制滚动条样式,超过10条显示滚动条
let scrollVisible = ref(false)
// 对外提供打开和关闭模态框,控制模态框和滚动条的显隐
defineExpose({ closeDialog, openDialog, dialogVisible, scrollVisible })
通过切换scrollVisible
的值为true/false
值来控制scrollDialog
这个样式是否展示。
2. 不同预处理器的样式穿透写法
在局部组件修改第三方组件的样式,且不影响该第三方组件在整个项目其他地方使用,可以使用样式穿透实现。
/deep/、::v-deep、:deep
都是深度选择器。
2.1. >>>
只作用于 css
// css穿透写法
<style scoped>
.scrollDialog >>> .el-dialog.el-dialog__body {
overflow-y: auto !important;
height: 400px !important;
}
</style>
2.2. ::v-deep或deep
只作用于 scss
:deep
是::v-deep
在Vue3
中的写法,两者功能一样
// scss穿透写法
<style lang="scss" scoped>
.scrollDialog ::v-deep .el-dialog.el-dialog__body {
overflow-y: auto !important;
height: 400px !important;
}
</style>
2.3. /deep/
只作用于 less
// less穿透写法
<style lang="less" scoped>
.scrollDialog /deep/ .el-dialog.el-dialog__body {
overflow-y: auto !important;
height: 400px !important;
}
</style>
项目使用的是sass,毅然选择了::v-deep,结果不生效。
已尝试的无效方法
1. 方法2.2。
2. 给el-dialog
加上custom-class
或class(el-plus官网给的属性),再对属性值进行修改。
解决办法
在el-dialog外部嵌套一层div元素,对其设置类名,在该元素下对需要修改的el-dialog__body
使用样式穿透。
<style lang="scss" scoped>
.scrollDialog {
:deep(.el-dialog__body) {
overflow-y: auto !important;
height: 400px !important;
}
}
</style>
//:deep 是 Vue 3 中对 ::v-deep 的别名,它们的用法完全相同