在 Vue 3 + Element Plus 开发中,若直接将 <el-drawer> 作为 <template> 的根元素(即上层是 <template>),Scoped CSS 样式将无法正确生效。
示例说明
样式失效的情况:
javascript
<template>
<el-drawer
v-model="drawer"
title="I am the title"
:direction="direction"
:before-close="handleClose"
>
<span>Hi, there!</span>
</el-drawer>
</template>
<style scoped>
:deep(.el-drawer) { /* 这些样式不会作用于内部元素 */ }
</style>
样式生效的正确做法:
javascript
<template>
<div class="drawer-wrapper">
<el-drawer
v-model="drawer"
title="I am the title"
:direction="direction"
:before-close="handleClose"
>
<span>Hi, there!</span>
</el-drawer>
</div>
</template>
<style lang="scss" scoped>
.drawer-wrapper {
/* 样式可正常生效 */
.el-drawer__header {
border-bottom: 1px solid #e8e8e8 !important;
margin-bottom: 0 !important;
}
}
</style>
通过外层包裹 <div>,Scoped CSS 的作用域锚定在该容器上,再通过 :deep() 深度选择器穿透到 <el-drawer> 及其内部结构,从而正确应用样式 。
核心原因
Vue 的 Scoped CSS 机制: Vue 会为组件模板中的每个元素注入唯一的 data-v-* 属性,并在编译时将 CSS 选择器重写为包含该属性的形式,以实现样式作用域隔离。
Element Plus 组件的内部结构:<el-drawer> 是一个复杂组件,其内部会动态生成多个子元素(如 .el-drawer__header、.el-drawer__body 等),这些子元素不会继承父组件的 data-v-* 属性。
当 <el-drawer> 直接作为根元素时: Scoped CSS 的作用域仅作用于 <el-drawer> 本身,而无法穿透到其内部动态生成的子元素,导致自定义样式失效 。
最后,附带一份重置`el-drawer`组件的CSS样式,包括z-index、位置、尺寸、背景色和字体大小,以及头部和主体部分的定制,可根据需要自行调整。
:deep(.el-drawer__wrapper) {
z-index: -3000!important;
.el-drawer {
position: relative;
left: 1100px;
top: 154px;
padding: 0;
width: 28.125vw !important;
height: 28.385vw;
background: rgba(7, 18, 26, 0.8);
font-size: 16px;
}
.el-drawer__header {
padding: 0 !important;
width: 520px !important;
height: 30px;
margin: 12px;
font-size: 16px;
color: #ffffFF;
background: rgba(19, 32, 42, 0.5) !important;
}
.el-drawer__body {
margin: 0px 10px 10px 10px;
background: rgba(19, 32, 42, 0.5) !important;
padding: 0;
width: 520px !important;
height: 340px;
position: relative;
}
}