使用样式穿透 ::v-deep 修改组件内部样式

183 阅读1分钟

场景

在 Vue 3 项目中,页面左侧使用了一个自定义封装的 TreeFilter 组件,内部集成了 el-scrollbar 来支持树形结构的滚动显示。组件结构如下:

<el-col :span="3">
  <tree-filter
    v-model="queryForm.code"
    ...
  />
</el-col>

在页面样式中需要调整左侧树区域的最大高度,首先尝试在el-col设置style,无效,查询子组件代码发现:

<!-- 使用 el-scrollbar 组件包裹 el-tree,设置最大高度为 300px,实现滚动效果 -->
    <el-scrollbar max-height="300px">
      <!-- 渲染 el-tree 组件 -->
      <el-tree
        v-if="!props.lazy || processedData.length > 0"
        ...
      />
    </el-scrollbar>

但子组件内容不方便修改。遂改为在父组件中对 el-scrollbar 设置 max-height 以控制高度:

<style scoped>
.el-scrollbar {
  max-height: 500px !important;
}
</style>

但样式仍未生效

问题原因

  1. 样式作用域限制:Vue 组件使用 scoped 样式时,默认样式不会影响子组件中的 DOM。
  2. Element Plus 内部结构封装复杂el-scrollbar 实际控制滚动区域的是内部的 .el-scrollbar__wrap 元素,而不是外层容器。
  3. 未使用深度穿透导致样式无效

解决方法

  1. 使用深度穿透 ::v-deep 修改内部 .el-scrollbar__wrap
<el-col class="tree-scroll-area" :span="3">
  <tree-filter ... />
</el-col>

<style scoped>
.tree-scroll-area ::v-deep(.el-scrollbar__wrap) {
  max-height: 500px !important;
}
</style>

说明:

  • ::v-deep 是深度样式穿透写法。
  • .el-scrollbar__wrap 是 Element Plus 中实际负责滚动的元素,必须指定它来控制高度。
  • 使用 !important 是为了解决 Element Plus 默认内联样式的覆盖问题。
  • 添加父容器 class 进行更精确限制,避免影响其他 el-scrollbar