常見的 el‐dialog 客製化技巧 - daniel-qa/Vue GitHub Wiki

常見的 el-dialog 客製化技巧

調整 el-dialog 的高度

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 機制

Teleport 是 Vue 3 提供的一种内建机制,让 DOM 节点脱离原位、挂载到指定宿主的机制,主要用来保证弹层的层级、可见性和交互一致性,(就是一定會彈出來)

設置 append-to-body 等於 false,可以讓組件停留在現有 DOM, 讓 style scoped 的設定生效

<el-dialog :append-to-body="false">...</el-dialog> 

但同時,也會造成父組的樣式渲染問題,和可能不會在銀幕正中央的位置(因為有更上層的父組件樣式可能影響)

範例2

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、且不會出現滾動或超框的效果。


el-dialog 的組件結構

+------------------------+
| 標題 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,避免影響其他組件。

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