SuperAPI AI Directory

el-dialog

General & other

View repository

Updated 10-15 23:32

About this skill

Element Plus Dialog Component

Informs users while preserving the current page state.

When to Invoke

Invoke this skill when:

  • User needs to display modal content
  • User wants to create confirmation dialogs
  • User needs form dialogs
  • User wants draggable dialogs
  • User needs nested dialogs
  • User asks about dialog customization

Features

  • Modal/Modeless: With or without overlay
  • Customizable Size: Width, height, fullscreen
  • Draggable: Drag dialog by header
  • Nested Support: Multiple dialog layers
  • Custom Content: Header, body, footer slots
  • Animations: Custom transition effects
  • Center Alignment: Horizontal and vertical centering
  • Destroy on Close: Clean up DOM when closed

API Reference

Dialog Attributes

Name Description Type Default
model-value / v-model visibility of Dialog boolean false
title title of Dialog string ''
width width of Dialog string | number ''
fullscreen whether fullscreen boolean false
top value for margin-top string ''
modal whether a mask is displayed boolean true
modal-penetrable whether the mask is penetrable boolean false
modal-class custom class names for mask string —
header-class custom class names for header string —
body-class custom class names for body string —
footer-class custom class names for footer string —
append-to-body whether to append Dialog to body boolean false
append-to which element the Dialog appends to CSSSelector | HTMLElement body
lock-scroll whether scroll of body is disabled boolean true
open-delay time before open (ms) number 0
close-delay time before close (ms) number 0
close-on-click-modal whether can be closed by clicking mask boolean true
close-on-press-escape whether can be closed by ESC boolean true
show-close whether to show close button boolean true
before-close callback before close (done: DoneFn) => void —
draggable enable dragging boolean false
overflow draggable can overflow viewport boolean false
center align header and footer in center boolean false
align-center align dialog horizontally and vertically boolean false
destroy-on-close destroy elements when closed boolean false
close-icon custom close icon string | Component —
z-index z-order of dialog number —
header-aria-level header's aria-level attribute string 2
transition custom transition configuration string | object dialog-fade

Dialog Slots

Name Description
default default content of Dialog
header content of the Dialog header
footer content of the Dialog footer

Dialog Events

Name Description Type
open triggers when Dialog opens () => void
opened triggers when opening animation ends () => void
close triggers when Dialog closes () => void
closed triggers when closing animation ends () => void
open-auto-focus triggers after Dialog opens and content focused () => void
close-auto-focus triggers after Dialog closed and content focused () => void

Dialog Exposes

Name Description Type
resetPosition reset position () => void
handleClose close dialog () => void

Usage Examples

Basic Dialog

<template>
  <el-button @click="dialogVisible = true">Open Dialog</el-button>

  <el-dialog v-model="dialogVisible" title="Tips" width="30%">
    <span>This is a message</span>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">Cancel</el-button>
        <el-button type="primary" @click="dialogVisible = false">Confirm</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref } from 'vue'

const dialogVisible = ref(false)
</script>

Custom Content

<template>
  <el-button @click="dialogVisible = true">Open Form Dialog</el-button>

  <el-dialog v-model="dialogVisible" title="Shipping Address" width="500">
    <el-form :model="form">
      <el-form-item label="Name" :label-width="formLabelWidth">
        <el-input v-model="form.name" autocomplete="off" />
      </el-form-item>
      <el-form-item label="Zone" :label-width="formLabelWidth">
        <el-select v-model="form.region" placeholder="Select">
          <el-option label="Zone No.1" value="shanghai" />
          <el-option label="Zone No.2" value="beijing" />
        </el-select>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="dialogVisible = false">Cancel</el-button>
      <el-button type="primary" @click="dialogVisible = false">Confirm</el-button>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, reactive } from 'vue'

const dialogVisible = ref(false)
const formLabelWidth = '140px'

const form = reactive({
  name: '',
  region: ''
})
</script>

Custom Header

<template>
  <el-dialog v-model="dialogVisible">
    <template #header="{ titleId, titleClass }">
      <div class="my-header">
        <h4 :id="titleId" :class="titleClass">Custom Header</h4>
        <el-button type="danger" @click="dialogVisible = false">
          <el-icon class="el-icon--left"><CircleCloseFilled /></el-icon>
          Close
        </el-button>
      </div>
    </template>
    This is content
  </el-dialog>
</template>

Nested Dialog

<template>
  <el-button @click="outerVisible = true">Open Outer Dialog</el-button>

  <el-dialog v-model="outerVisible" title="Outer Dialog">
    <el-button @click="innerVisible = true">Open Inner Dialog</el-button>
    
    <el-dialog
      v-model="innerVisible"
      title="Inner Dialog"
      append-to-body
    />
  </el-dialog>
</template>

<script setup>
import { ref } from 'vue'

const outerVisible = ref(false)
const innerVisible = ref(false)
</script>

Centered Content

<template>
  <el-dialog v-model="dialogVisible" title="Tips" width="30%" center>
    <span>Content should be centered</span>
    <template #footer>
      <el-button @click="dialogVisible = false">Cancel</el-button>
      <el-button type="primary" @click="dialogVisible = false">Confirm</el-button>
    </template>
  </el-dialog>
</template>

Align Center

<template>
  <el-dialog v-model="dialogVisible" title="Tips" width="30%" align-center>
    <span>Dialog is centered both horizontally and vertically</span>
  </el-dialog>
</template>

Draggable Dialog

<template>
  <el-dialog v-model="dialogVisible" title="Tips" draggable>
    <span>Drag the header to move the dialog</span>
  </el-dialog>
</template>

Fullscreen

<template>
  <el-dialog v-model="dialogVisible" title="Tips" fullscreen>
    <span>Fullscreen dialog</span>
  </el-dialog>
</template>

Before Close

<template>
  <el-dialog
    v-model="dialogVisible"
    title="Tips"
    :before-close="handleClose"
  >
    <span>This dialog will ask for confirmation before closing</span>
  </el-dialog>
</template>

<script setup>
import { ref } from 'vue'
import { ElMessageBox } from 'element-plus'

const dialogVisible = ref(false)

const handleClose = (done) => {
  ElMessageBox.confirm('Are you sure to close this dialog?')
    .then(() => {
      done()
    })
    .catch(() => {
      // catch error
    })
}
</script>

Destroy on Close

<template>
  <el-dialog v-model="dialogVisible" destroy-on-close>
    <span>Content will be destroyed when closed</span>
  </el-dialog>
</template>

Modal Configuration

<template>
  <!-- No modal overlay -->
  <el-dialog v-model="dialogVisible" :modal="false">
    <span>Dialog without modal overlay</span>
  </el-dialog>
</template>

Custom Animation

<template>
  <el-dialog v-model="dialogVisible" transition="el-zoom-in-top">
    <span>Dialog with custom animation</span>
  </el-dialog>
</template>

Common Issues

1. Scoped Styles Not Working

Dialog uses Teleport, so styles should be global:

<style>
/* Global styles for dialog */
.my-dialog .el-dialog__body {
  padding: 20px;
}
</style>

2. Page Scroll Issues

Use lock-scroll properly:

<el-dialog v-model="dialogVisible" lock-scroll>
  <!-- content -->
</el-dialog>

3. Nested Dialog Positioning

Use append-to-body for nested dialogs:

<el-dialog v-model="outer">
  <el-dialog v-model="inner" append-to-body />
</el-dialog>

Component Interactions

With Form

<template>
  <el-dialog v-model="dialogVisible" title="Edit User">
    <el-form :model="form" :rules="rules" ref="formRef">
      <el-form-item label="Name" prop="name">
        <el-input v-model="form.name" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="dialogVisible = false">Cancel</el-button>
      <el-button type="primary" @click="handleSubmit">Save</el-button>
    </template>
  </el-dialog>
</template>

<script setup>
const handleSubmit = async () => {
  try {
    await formRef.value.validate()
    await saveUser(form)
    dialogVisible.value = false
  } catch (error) {
    console.error('Validation failed')
  }
}
</script>

With Table

<template>
  <el-dialog v-model="dialogVisible" title="Select Items" width="70%">
    <el-table :data="tableData" @selection-change="handleSelection">
      <el-table-column type="selection" />
      <el-table-column prop="name" label="Name" />
    </el-table>
  </el-dialog>
</template>

Best Practices

  1. Use v-model: Always use v-model for visibility control
  2. Set width: Set appropriate width for content
  3. Use before-close: Handle unsaved changes gracefully
  4. Destroy on close: Use destroy-on-close for performance
  5. Nested dialogs: Always use append-to-body for nested dialogs
  6. Accessibility: Use proper title and aria-level