v‐deep ‐ 深度选择器在vue3不生效的問題 - daniel-qa/Vue GitHub Wiki

v-deep - 深度选择器在vue3不生效的問題

在 Vue 3 中,el-dialog 等一些组件(比如 el-dropdown)可以使用 append-to-body 属性(Element UI屬性 ),它将组件的内容直接插入到 body 中。这可能导致你在使用 ::v-deep 或全局样式时,无法直接修改这些内容的样式。

解决方法是:

  • 使用全局样式 如果你想修改全局范围内的 el-radio 字体大小,可以通过全局 CSS 来实现。
/* global.css 或在 scoped 样式外部 */
<style>
.el-radio__label {
  font-size: 18px;
}
</style>

设置 append-to-body="false",将 el-dialog 或其他组件的内容渲染到组件内部,而不是 body 中,这样就可以通过 scoped 样式或者深度选择器 ::v-deep 来修改样式

<template>
  <el-dialog :visible.sync="dialogVisible" append-to-body="false">
    <el-radio-group v-model="selectedOption">
      <el-radio label="option1">选项 1</el-radio>
      <el-radio label="option2">选项 2</el-radio>
    </el-radio-group>
  </el-dialog>
</template>

<script>
export default {
  data() {
    return {
      dialogVisible: false,
      selectedOption: 'option1',
    };
  },
};
</script>

<style scoped>
/* 使用 ::v-deep 修改 el-radio 样式 */
::v-deep .el-radio {
  font-size: 20px;
  color: red;
}
</style>

::v-deep 和 append-to-body 配合使用的问题

由于 el-dialog 在 Vue 3 中被渲染到 body 中,即使它被嵌套在父组件的 div 中,样式选择器(如 ::v-deep)可能无法正常生效

原因如下:

el-dialog 被渲染到 body 下,与当前组件的样式作用域并不在同一 DOM 树中

深度选择器 只能穿透当前组件内的样式封装(通过 scoped 样式),无法影响全局或其他非当前组件内的元素

解决方法

解决这个问题的方式有两种:

  • 1 . 为 el-dialog 添加外部 div 包裹元素

    通过在

<template>
  <div>
    <el-dialog :visible.sync="dialogVisible" append-to-body="false">
      <!-- Dialog content goes here -->
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dialogVisible: false,
    };
  }
};
</script>

<style scoped>
/* 使用 ::v-deep 或 :deep 修改 el-dialog 样式 */
::v-deep .el-dialog {
  background-color: red;
}
</style>

通过这种方式,el-dialog 被包裹在 div 中,因此它将会被渲染在当前组件的 DOM 树中,深度选择器(::v-deep 或 :deep())就能正常应用

  • 2 . 修改 append-to-body 属性

另一种方法是通过修改 append-to-body 属性,将 el-dialog 的渲染方式调整为渲染在 body 中。然后,如果你仍然需要修改 el-dialog 样式,可以使用全局 CSS 或者使用其他方式来应用样式。

<template>
  <el-dialog :visible.sync="dialogVisible" append-to-body>
    <!-- Dialog content goes here -->
  </el-dialog>
</template>

<script>
export default {
  data() {
    return {
      dialogVisible: false,
    };
  }
};
</script>

<style scoped>
/* 修改 el-dialog 的样式可以通过全局样式 */
.el-dialog {
  background-color: red;
}
</style>

在这种情况下,由于 el-dialog 渲染到 body 中,因此样式选择器就不再需要依赖深度选择器,直接通过全局样式或父组件的样式修改即可。

⚠️ **GitHub.com Fallback** ⚠️