vue 組件中使用了 element-plus 組件
<template><el-dialog:model-value="visible":title="title":width="width + 'px'":before-close="onClose"><div class="container" :style="{height:height + 'px'}"><slot name="content"></slot></div><template #footer><div class="dialog-footer"><el-button plain type="danger" @click="onClose">取消</el-button><el-button plain type="primary" @click="onConfirm">確定</el-button></div></template></el-dialog>
</template>
<style lang="scss" scoped>
// 組件內自定義的 elementplus 的樣式,
:deep(.el-dialog){border-radius: 10px!important;background-color: #535bf2;
}
使用了:deep()失效
bug 剖析
1. 組件的樣式與第三方子組件樣式的加載順序
- 若第三方子組件是完全引入的,比如 element-plus:子組件在應用啟動的時候,樣式就加載了
- 若第三方子組件是按需導入的,那么先加載組件,然后加載子組件。
2. 樣式中scoped
當在一個Vue SFC的<style>
標簽中添加scoped屬性時,Vue編譯器會為該組件內的所有元素添加一個唯一的屬性(例如data-v-f3f3eg9),同時修改樣式規則以匹配這個屬性。這意味著這些樣式只會應用于當前組件內的元素,而不會影響全局或其他組件中的相同類名或標簽。
示例:
<template><div class="example">Hello, scoped CSS!</div>
</template><style scoped>
.example {color: red;
}
</style>
編譯后可能會變成類似這樣:
<template><div class="example" data-v-f3f3eg9>Hello, scoped CSS!</div>
</template><style>
.example[data-v-f3f3eg9] {color: red;
}
</style>
3. :deep()失效原因
<template><el-dialog:model-value="visible":title="title":width="width + 'px'":before-close="onClose"><div class="container" :style="{height:height + 'px'}"><slot name="content"></slot></div><template #footer><div class="dialog-footer"><el-button plain type="danger" @click="onClose">取消</el-button><el-button plain type="primary" @click="onConfirm">確定</el-button></div></template></el-dialog>
</template>
<style lang="scss" scoped>
// 組件內自定義的 elementplus 的樣式,
:deep(.el-dialog){border-radius: 10px!important;background-color: #535bf2;
}
- 子組件是完全引入的,那么先加載子組件,后加載該組件。
- 組件的
<template></template>
中只含有子組件,那么組件的樣式會覆蓋子組件的樣式 - 加載父組件的時候,由于子組件已加載完成,Vue 編譯器無法為組件中的元素(即子組件)添加唯一屬性,也就無法將組件的樣式綁定到子組件。
故,使用:deep()
,樣式依然失效。
解決辦法
在組件的<template></template>
中,將子組件放入到<div></div>
標簽中,那么在加載組件的時候,組件的樣式會綁定到<div></div>
標簽上。
<template><div><el-dialog:model-value="visible":title="title":width="width + 'px'":before-close="onClose"><div class="container" :style="{height:height + 'px'}"><slot name="content"></slot></div><template #footer><div class="dialog-footer"><el-button plain type="danger" @click="onClose">取消</el-button><el-button plain type="primary" @click="onConfirm">確定</el-button></div></template></el-dialog></div>
</template>