ワンクリックで
el-plus-crud-dialog
Dialog wrapper for ElPlusForm and ElPlusFormGroup with auto open/close, submit handling, and table reload coordination
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Dialog wrapper for ElPlusForm and ElPlusFormGroup with auto open/close, submit handling, and table reload coordination
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Configuration system and TypeScript types for el-plus-crud — ICRUDConfig, IFormDesc, ITableConfig, provide/inject dependency injection
Multi-section grouped form with independent validation per group, shared submit lifecycle, and dynamic group visibility
Data-driven form component with 40+ field types, dynamic visibility, multi-column layout, submit lifecycle hooks, and field-level linking
Proven patterns and recipes for common CRUD scenarios — complete CRUD page, search-reset workflow, master-detail, custom components, and permission control
Vue 3 + Element Plus data-driven CRUD component library — entry skill for all components and configuration
Data-driven table component with multi-level headers, pagination, tabs, row selection, export, summary rows, and tree expansion
| 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 wraps ElPlusForm or ElPlusFormGroup inside an el-dialog, providing a standard pattern for add/edit dialogs. It supports two modes:
formDesc for field descriptorsformGroup for multi-section formsBoth 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.
<ElPlusFormDialog> componentformGroup| 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.
<!-- formDesc mode -->
<ElPlusFormDialog
v-model="formData"
v-model:show="showDialog"
:formDesc="formDesc"
/>
<!-- formGroup mode -->
<ElPlusFormDialog
v-model="formData"
v-model:show="showDialog"
:formGroup="formGroupConfig"
/>
v-model — form data objectv-model:show — dialog visibilityPass 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:
ElMessage.success(successTip)tableRef.reload()callBack() to reset form loading state| 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 |
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()
interface ElPlusFormDialogProps {
modelValue?: { [key: string]: any } // Form data (two-way)
formDesc?: IFormDesc // Form field descriptors (formDesc mode)
formGroup?: IFormGroupConfig // Grouped form config (formGroup mode)
show?: boolean // Dialog visibility (two-way)
title?: string // Dialog title
tableRef?: any // ElPlusTable ref for auto-reload
success?: Function // Custom success callback
isLoading?: boolean // External loading state
successTip?: string | ((data?) => string) // Success message (default: '操作成功!')
}
| 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}).
const dialogRef = ref()
dialogRef.value.submit() // Manually trigger form submit (formDesc mode) / validate (formGroup mode)
dialogRef.value.validate() // Validate all form fields
dialogRef.value.getData() // Get merged form data
dialogRef.value.clearValid() // Clear validation state
dialogRef.value.clear() // Clear form data
dialogRef.value.init() // Re-initialize form
<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>
const handleEdit = (row: any) => {
// Assign existing data — form auto-fills
formData.value = { ...row }
showDialog.value = true
}
<!-- Same dialog handles both add and edit -->
<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.
<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:
formGroup instead of formDesc to switch to grouped modetableRef auto-reload works the same way as formDesc modeprops.success → formGroup.success → default (reload + close)<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.
<ElPlusFormDialog
v-model:show="showDialog"
v-model="formData"
:formDesc="formDesc"
:requestFn="api.create"
:success="handleSuccess"
/>
const handleSuccess = ({ response, formData, callBack }: IFormBack) => {
// Custom logic — no auto table reload or dialog close
ElMessage.success(`创建成功,ID: ${response.id}`)
showDialog.value = false
callBack() // Must call to reset loading state
}
// FAIL: Don't manually manage dialog state and form data
const open = () => {
showDialog.value = true
formData.value = { name: '' }
}
const close = () => {
showDialog.value = false
formRef.value.clear()
}
<ElPlusFormDialog v-model:show="showDialog" v-model="formData" :formDesc="formDesc" />
// FAIL: Customized success but forgot to reload table
success: (formBack) => {
ElMessage.success('操作成功')
// Missing: tableRef.reload() or formBack.callBack()
}
// Option 1: Pass tableRef — fully automatic
<ElPlusFormDialog :tableRef="tableRef" />
// Option 2: Manual — ensure reload and callBack
success: ({ response, formData, callBack }) => {
tableRef.value?.reload()
callBack()
}
<!-- FAIL: No need for a separate component -->
<ElPlusFormGroupDialog v-model:show="showDialog" :formGroup="formGroupConfig" />
<ElPlusFormDialog v-model:show="showDialog" :formGroup="formGroupConfig" />
tableRef to enable fully automatic add/edit workflow (both modes)destroyOnClose: true (default) for clean state on each openv-model — form auto-fills all fieldstitle and successTip to differentiate add vs edit: formData.id ? '编辑' : '新增'el-dialog props pass through via attrs: width, top, appendToBody, etc.formGroup mode when form fields need to be organized into titled sectionsprops.success (highest) → formGroup.success → default behaviorel-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)