常見的 el‐dialog 客製化技巧 - daniel-qa/Vue GitHub Wiki
p.s 要用全域的設定,官網文件有寫
- 最主要是設定 my-custom-dialog 的 Class (因為是全域,要指定避免渲染),
和直接設定最外層的 el-dialog 的高度(因有套用 class, 直接在 .my-custom-dialog 設定高度
和透過 .my-custom-dialog .el-dialog__body 的方式,指定 body 的高度
- 其他部分,就再看怎麼調,(太細部先不考慮,後面再調整)
<template>
<!-- 召喚按鈕 -->
<el-button type="primary" @click="openDialog">
開啟對話框
</el-button>
<div>
<el-dialog class="my-custom-dialog"
v-model="dialogVisible"
width="30%">
<!-- 內容 -->
我是內容
</el-dialog>
</div>
</template>
<script setup>
import { ref } from 'vue'
const dialogVisible = ref(true)
function openDialog() {
dialogVisible.value = true
}
</script>
<style>
/* 全域生效,非 scoped */
.my-custom-dialog {
border-radius: 12px;
background-color: #f9f9f9;
/* 固定高度 */
height: 300px;
}
/* 限制內容區高度並滾動 */
.my-custom-dialog .el-dialog__body {
height: 250px;
}
</style>
Teleport 是 Vue 3 提供的一种内建机制,让 DOM 节点脱离原位、挂载到指定宿主的机制,主要用来保证弹层的层级、可见性和交互一致性,(就是一定會彈出來)
設置 append-to-body 等於 false,可以讓組件停留在現有 DOM, 讓 style scoped 的設定生效
<el-dialog :append-to-body="false">...</el-dialog>
但同時,也會造成父組的樣式渲染問題,和可能不會在銀幕正中央的位置(因為有更上層的父組件樣式可能影響)
css 設定參考
<style>
/* 全域生效,非 scoped */
.dialogModifyTimeStyle {
border-radius: 12px;
background-color: #f9f9f9;
/* 固定高度 */
height: 300px;
}
/* 限制內容區高度並滾動 */
.dialogModifyTimeStyle .el-dialog__body {
height: 100px;
}
/* 限制內容區高度並滾動 */
.dialogModifyTimeStyle .el-dialog__header {
height: 40px;
}
</style>
參考
- 可以把這個流程想像成多層蛋糕,最外層往裡面一層一層調,最後鎖定內容區
// 設定 Dialog,要計算的公式
bodyHeight = dialogHeight – headerHeight – footerHeight
- 實際的 CSS 設定
.multi-dialog::v-deep(.el-dialog__body) {
height: calc(
var(--dialog-height, 600px)
- var(--header-height, 50px)
- var(--footer-height, 46px)
);
overflow: visible; /* 或 auto/hidden,看需求 */
}
- < el-dialog > 會渲染出一個 .el-dialog 容器,裡面有 .el-dialog__header、.el-dialog__body、.el-dialog__footer 三個部分。
我們想改變「內容區高度」就要下在 .el-dialog__body 上,所以在 scoped 樣式裡寫:
.my-dialog::v-deep(.el-dialog__body) {
height: calc(600px - 96px);
overflow: visible;
}
- .dialog-content 是放在 template 裡 .el-dialog__body 裡面的子容器,你可以用它來做 padding、flex、grid 之類的排版設定,
但它本身並不影響 .el-dialog__body 的高度(除非你對它額外寫了 CSS)。
所以:
調整高度 → 寫在 ::v-deep(.el-dialog__body)
做內距/排版 → 寫在你自訂的 .dialog-content
calc(600px - 96px) 就是「600px 的總高度,減掉上下兩塊的高度」,結果就是 內容區(.el-dialog__body)應該要多高,才能讓整個對話框剛好 600px、且不會出現滾動或超框的效果。
+------------------------+
| 標題 Title(header) |
+------------------------+
| 內容區(body)高度你想設多高就設多高 |
| 這邊可以滾動! |
+------------------------+
| 按鈕區(footer) |
+------------------------+
.el-dialog 是整個 Dialog 的容器
.el-dialog__header 是標題區
.el-dialog__body 是內文區(你剛說的中間)
.el-dialog__footer 是底部按鈕區
- 1 . 使用 custom-class 或 class 進行樣式覆蓋 在 Element Plus 中,為了避免全局樣式污染,建議為特定的 Dialog 添加自定義類名,然後針對該類名進行樣式調整。例如:
<el-dialog
v-model="dialogVisible"
class="custom-dialog"
append-to-body
>
<!-- Dialog 內容 -->
</el-dialog>
.custom-dialog .el-dialog__header {
padding: 0;
background-color: #f5f5f5;
}
.custom-dialog .el-dialog__body {
padding: 20px;
}
.custom-dialog .el-dialog__footer {
padding: 10px 20px;
}
這樣的做法可以確保樣式只作用於特定的 Dialog,避免影響其他組件。