| name | el-plus-crud-dialog |
| description | Dialog wrapper for ElPlusForm and ElPlusFormGroup with auto open/close, submit handling, and table reload coordination |
| version | 1.1.0 |
| origin | el-plus-crud |
| tags | ["vue3","element-plus","dialog","form-dialog","modal-form","form-group-dialog"] |
ElPlusFormDialog — Dialog Form
ElPlusFormDialog wraps ElPlusForm or ElPlusFormGroup inside an el-dialog, providing a standard pattern for add/edit dialogs. It supports two modes:
- formDesc mode (original): Standard form dialog, pass
formDesc for field descriptors
- formGroup mode (new): Grouped form dialog, pass
formGroup for multi-section forms
Both modes share the same dialog lifecycle: open → init form, close → clear data, submit success → close dialog + refresh linked table. Core value: one component completes the full "click button → open dialog → fill form → submit → close → refresh list" workflow.
When to Activate
- Using
<ElPlusFormDialog> component
- Implementing add/edit modal functionality
- Coordinating dialog with table reload
- Configuring dialog width and form integration
- Building grouped/sectioned form dialogs with
formGroup
Core Concepts
Two Modes
| Mode | Prop | Renders | Use Case |
|---|
formDesc (default) | :formDesc="formDesc" | ElPlusForm | Simple flat form |
formGroup | :formGroup="formGroupConfig" | ElPlusFormGroup | Multi-section grouped form |
When formGroup is provided, it takes priority and renders ElPlusFormGroup. Otherwise, falls back to ElPlusForm with formDesc. Fully backward compatible — existing formDesc usage requires zero changes.
Two-way Bindings
<ElPlusFormDialog
v-model="formData"
v-model:show="showDialog"
:formDesc="formDesc"
/>
<ElPlusFormDialog
v-model="formData"
v-model:show="showDialog"
:formGroup="formGroupConfig"
/>
v-model — form data object
v-model:show — dialog visibility
tableRef Coordination
Pass a table ref to automatically reload the table after successful submit (works in both modes):
<ElPlusTable ref="tableRef" :tableConfig="tableConfig" />
<ElPlusFormDialog v-model:show="showDialog" v-model="formData" :formDesc="formDesc" :tableRef="tableRef" />
When tableRef is provided and no custom success callback:
- Shows
ElMessage.success(successTip)
- Calls
tableRef.reload()
- Closes the dialog
- Calls
callBack() to reset form loading state
Dialog Default Configuration
| Property | Default | Description |
|---|
width | '700px' | Dialog width |
draggable | true | Dialog is draggable |
top | '15vh' | Top offset |
closeOnClickModal | false | Clicking overlay won't close |
destroyOnClose | true | Destroy form on close |
showCancel | true | Show cancel button |
Lifecycle
User clicks "新增/编辑" → set formData + showDialog=true
→ dialog opened → formRef.init()
→ user fills form → clicks "提交"
→ ElPlusForm/ElPlusFormGroup submit lifecycle runs
→ success → tableRef.reload() + close dialog
→ dialog closed → formRef.clear()
Props
interface ElPlusFormDialogProps {
modelValue?: { [key: string]: any }
formDesc?: IFormDesc
formGroup?: IFormGroupConfig
show?: boolean
title?: string
tableRef?: any
success?: Function
isLoading?: boolean
successTip?: string | ((data?) => string)
}
Slots
| Slot | Mode | Description |
|---|
header | Both | Custom dialog header |
top | formDesc only | Content above form |
default | formDesc only | Content inside form area |
footer | Both | Custom dialog footer |
Note: top and default slots are only available in formDesc mode. In formGroup mode, use ElPlusFormGroup's named slots (title{index}, top{index}, default{index}).
Expose Methods
const dialogRef = ref()
dialogRef.value.submit()
dialogRef.value.validate()
dialogRef.value.getData()
dialogRef.value.clearValid()
dialogRef.value.clear()
dialogRef.value.init()
Code Examples
Basic Add Dialog (formDesc mode)
<template>
<ElPlusTable ref="tableRef" :tableConfig="tableConfig" />
<ElPlusFormDialog
v-model:show="showDialog"
v-model="formData"
:formDesc="formDesc"
:requestFn="api.createUser"
:tableRef="tableRef"
title="新增用户"
/>
</template>
<script setup>
const showDialog = ref(false)
const formData = ref({})
const formDesc = {
name: { type: 'input', label: '姓名', required: true },
phone: { type: 'input', label: '手机号', rules: 'phone' },
email: { type: 'input', label: '邮箱', rules: 'email' }
}
const handleAdd = () => {
formData.value = {}
showDialog.value = true
}
</script>
Edit Dialog (Shared with Add)
const handleEdit = (row: any) => {
formData.value = { ...row }
showDialog.value = true
}
<ElPlusFormDialog
v-model:show="showDialog"
v-model="formData"
:formDesc="formDesc"
:requestFn="api.createUser"
:updateFn="api.updateUser"
:tableRef="tableRef"
:title="formData.id ? '编辑用户' : '新增用户'"
:successTip="formData.id ? '编辑成功!' : '新增成功!'"
/>
When formData has an id field (default idKey: 'id'), updateFn is called instead of requestFn.
Grouped Form Dialog (formGroup mode)
<template>
<ElPlusTable ref="tableRef" :tableConfig="tableConfig" />
<ElPlusFormDialog
v-model:show="showDialog"
v-model="formData"
:formGroup="formGroupConfig"
title="编辑用户信息"
:tableRef="tableRef"
/>
</template>
<script setup>
const formGroupConfig: IFormGroupConfig = {
column: 2,
requestFn: api.saveUser,
successTip: '保存成功!',
group: [
{
title: '基本信息',
formDesc: {
name: { type: 'input', label: '姓名', required: true },
phone: { type: 'input', label: '手机号', rules: 'phone' }
}
},
{
title: '地址信息',
formDesc: {
province: { type: 'area', label: '地区', required: true },
address: { type: 'input', label: '详细地址' }
}
},
{
title: '备注',
formDesc: {
remark: { type: 'textarea', label: '备注信息', colspan: 2 }
}
}
]
}
</script>
Key points:
- Pass
formGroup instead of formDesc to switch to grouped mode
tableRef auto-reload works the same way as formDesc mode
- Success callback priority:
props.success → formGroup.success → default (reload + close)
Custom Width and Attributes
<ElPlusFormDialog
v-model:show="showDialog"
v-model="formData"
:formDesc="formDesc"
width="900px"
top="10vh"
:appendToBody="true"
/>
All el-dialog attributes pass through: width, top, modal, appendToBody, showClose, draggable, closeOnClickModal, destroyOnClose.
Custom Success Callback
<ElPlusFormDialog
v-model:show="showDialog"
v-model="formData"
:formDesc="formDesc"
:requestFn="api.create"
:success="handleSuccess"
/>
const handleSuccess = ({ response, formData, callBack }: IFormBack) => {
ElMessage.success(`创建成功,ID: ${response.id}`)
showDialog.value = false
callBack()
}
Anti-Patterns
FAIL: Manually control dialog open/close lifecycle
const open = () => {
showDialog.value = true
formData.value = { name: '' }
}
const close = () => {
showDialog.value = false
formRef.value.clear()
}
PASS: Use v-model:show, component auto-handles lifecycle
<ElPlusFormDialog v-model:show="showDialog" v-model="formData" :formDesc="formDesc" />
FAIL: Custom success without table reload
success: (formBack) => {
ElMessage.success('操作成功')
}
PASS: Pass tableRef for auto-reload, or handle manually
<ElPlusFormDialog :tableRef="tableRef" />
success: ({ response, formData, callBack }) => {
tableRef.value?.reload()
callBack()
}
FAIL: Create separate ElPlusFormGroupDialog for grouped forms
<ElPlusFormGroupDialog v-model:show="showDialog" :formGroup="formGroupConfig" />
PASS: Use ElPlusFormDialog with formGroup prop
<ElPlusFormDialog v-model:show="showDialog" :formGroup="formGroupConfig" />
Best Practices
- Pass
tableRef to enable fully automatic add/edit workflow (both modes)
- Keep
destroyOnClose: true (default) for clean state on each open
- For edit mode, pass existing data via
v-model — form auto-fills all fields
- Use dynamic
title and successTip to differentiate add vs edit: formData.id ? '编辑' : '新增'
- All
el-dialog props pass through via attrs: width, top, appendToBody, etc.
- Use
formGroup mode when form fields need to be organized into titled sections
- Success callback priority:
props.success (highest) → formGroup.success → default behavior
Related Skills
el-plus-crud-form — ElPlusFormDialog internally uses ElPlusForm in formDesc mode; all formDesc and form configurations apply (direct)
el-plus-crud-form-group — ElPlusFormDialog internally uses ElPlusFormGroup in formGroup mode; all formGroup configurations apply (direct)
el-plus-crud-config — IFormDesc / IFormGroupConfig type definitions (indirect)
el-plus-crud-table — tableRef parameter references ElPlusTable instance (indirect)
el-plus-crud-validation — formDesc rules configuration (indirect)