DialogForm 对话框表单
基于 uniboot-ui 的 UDialog / UDrawer 与 UForm 封装的 弹层表单:通过 variant 选择 居中对话框 或 侧滑抽屉,共用同一套 fields、校验、onFinish、描述区与插槽。默认 variant="dialog"。
TIP
由 uniboot-ui 提供;import { DialogForm } from 'uniboot-ui'。模板中可使用 <dialog-form />。包内仍导出 DrawerForm / <drawer-form /> 作为 variant="drawer" 的便捷封装(可选)。
何时使用
- 需要 弹窗或抽屉 + 配置化字段,而不希望手写整页
UFormItem时。 - 提交逻辑为 异步接口:希望在
onFinish内统一处理 loading、成功关闭、失败保持打开。
variant:对话框与抽屉
variant 值 | 容器 | 说明 |
|---|---|---|
dialog(默认) | UDialog | 透传 width;表单区为 双列 Grid,小屏单列。 |
drawer | UDrawer | 透传 size、direction;表单栅格由 columns(1 | 2)控制;底部可选 footerTopBorder。 |
两种模式下 打开重置模型、finish / onFinish、return false 不关闭、loading \|\| submitting 等行为一致。文档示例均可在 对话框 / 抽屉 间切换预览。
切换 对话框 / 抽屉 后打开同一表单,提交结果用消息区分。
显示与提交流程
- 使用
v-model:visible控制显隐;每次 打开 时会根据fields与initialValues重置内部表单模型。 - 点击 确定:先走 uniboot-ui 表单校验,通过后依次
emit('finish', values)、再执行onFinish(若传入)。 onFinish返回false或Promise<false>时 不关闭 当前弹层;返回true、undefined或未定义返回值时 关闭(与内部undefined结果一致)。- 确定按钮 的 loading 为
loading || submitting:submitting在onFinish为 Promise 期间为true;也可由父组件通过loading单独控制。
基础用法
fields 配置列;onFinish 处理提交(可 async)。
新增员工:含描述文案、多字段与 @finish / @cancel 示例。
字段类型
type 省略时等价于 input。下拉须配置 options。
| type | 说明 | 控件 |
|---|---|---|
input | 单行文本 | UInput |
select | 下拉 | USelect |
date | 日期 | UDatePicker |
textarea | 多行文本 | UInput type="textarea" |
number | 数字 | UInput type="number" |
展示各 type;提交成功使用 UMessage.success 提示。
初始值与编辑
initialValues 为 Record<string, unknown>,键与 fields[].key 对应;未提供的键会初始化为空字符串 ''。
打开即回显姓名、邮箱、部门,保存后提示成功。
提交失败时保持打开
业务错误(如唯一键冲突)时 return false,弹层保持打开,便于用户修改后再次提交。
首次提交模拟冲突;再次提交成功。
描述区:description 与插槽
description属性:展示内置信息条样式(图标 + 文案)。#description插槽:完全自定义 描述区内容;只要提供了该插槽,就不再使用description属性。
使用 #description 自定义布局与样式。
布局说明
variant="dialog":表单区域为 双列 CSS Grid(repeat(2, 1fr)),表单项自上而下、从左到右填充;视口宽度 ≤ 768px 时为 单列。variant="drawer":由columns控制1单列或2双列(双列时小屏同样降为单列)。- 某项需在双列下 独占一行 时,在该字段上设置
colSpan: 2(例如备注、长文本域)。
双列中「备注」使用 colSpan: 2 占满一行。
自定义表单项:#field-{key} 插槽
当某一列需要 输入框 + 附属操作(如校验、复制、扫码)等组合布局时,可为该字段提供 #field-{key} 插槽,完全替换该项的默认控件;UFormItem 的标签与校验 prop 仍由 fields 配置,与内置渲染一致。
- 插槽名与字段
key对应:例如key: 'kcv'时使用#field-kcv;key: 'externalKeyRef'时使用#field-externalKeyRef。 - 作用域参数:
model为表单响应式对象(可与v-model="model.xxx"双向绑定);field为当前字段配置项。
与示意图一致:双列表单项 + KCV 行内 输入框 +「检验」主按钮(其余列仍走配置化渲染)。
自定义校验
除 required: true 外,可通过 rules 传入与 UForm 一致的规则数组;若同时 required,内置必填规则会排在前面。
import type { DialogFormField } from 'uniboot-ui'
const fields: DialogFormField[] = [
{
key: 'email',
label: '邮箱',
required: true,
rules: [{ type: 'email', message: '请输入正确邮箱', trigger: 'blur' }],
},
]DialogForm 属性
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| variant | 承载方式:dialog 对话框,drawer 抽屉 | enum | dialog |
| visible | 是否显示,使用 v-model:visible | boolean | false |
| title | 标题 | string | 标题文本 |
| description | 描述文案(表单上方信息条);与 #description 插槽 互斥,有插槽时忽略属性 | string | '' |
| fields | 表单字段配置 | array | [] |
| initialValues | 打开时的初始值 | object | {} |
| loading | 确定按钮额外 loading(会与内部提交态叠加) | boolean | false |
| confirmText | 确定按钮文案 | string | 确定 |
| cancelText | 取消按钮文案 | string | 取消 |
| onFinish | 校验通过后的提交回调;返回 false 时不关闭 | Function | — |
| width | variant="dialog" 时:宽度,透传 UDialog | string / number | 720 |
| size | variant="drawer" 时:尺寸,透传 UDrawer | string / number | 520 |
| direction | variant="drawer" 时:打开方向,透传 UDrawer | enum | rtl |
| columns | variant="drawer" 时:表单栅格列数 1 单列 / 2 双列 | enum | 2 |
| footerTopBorder | variant="drawer" 时:底部操作区顶部分隔线 | boolean | true |
| showClose | 是否显示右上角关闭按钮 | boolean | true |
事件
| 名称 | 说明 | 类型 |
|---|---|---|
| finish | 校验通过后、调用 onFinish 之前触发,参数为当前表单值 | Function |
| cancel | 用户取消或关闭时触发(如点击取消、关闭图标等) | Function |
| update:visible | 显隐变化 | Function |
插槽
| 名称 | 说明 |
|---|---|
| description | 自定义描述区域;存在时 不使用 description 属性 |
field-{key} | 覆盖 fields 中对应 key 的控件区(不含标签);作用域参数 model、field(见上文「自定义表单项」) |
| footer | 自定义底部操作区;未提供 时为默认「取消 + 确定」。提供插槽即 整区替换,可通过作用域参数调用提交/取消(见下表) |
footer 作用域参数
| 参数 | 说明 |
|---|---|
| submit | 与默认「确定」相同:校验通过后执行 finish / onFinish 及关闭逻辑 |
| cancel | 与默认「取消」相同:关闭并触发 cancel 事件 |
| loading | 提交中状态(loading 与内部 submitting 的合并结果),用于主按钮 loading |
<dialog-form
v-model:visible="visible"
title="编辑"
:fields="fields"
:on-finish="onFinish"
>
<template #footer="{ submit, cancel, loading }">
<div style="display: flex; justify-content: flex-end; gap: 12px; padding-top: 12px">
<u-button @click="cancel">放弃</u-button>
<u-button type="primary" :loading="loading" @click="submit">保存</u-button>
</div>
</template>
</dialog-form>DialogFormField
| 名称 | 说明 | 类型 | 必填 |
|---|---|---|---|
| key | 字段唯一标识(表单 model 的键) | string | 是 |
| label | 标签文案 | string | 是 |
| type | 字段类型,见上表 | enum | 否 |
| placeholder | 占位符 | string | 否 |
| required | 是否必填(生成一条默认 blur 规则) | boolean | 否 |
| rules | 追加/自定义规则(与 UForm FormRules 一致) | array | 否 |
| options | type === 'select' 时的选项 | array | 否 |
| colSpan | 双列下横向占位:1 占半行,2 独占一行(占满整行);小屏单列时与 1 相同 | enum | 否(默认 1) |
DialogFormValues
表单值类型:object(各字段实际类型由控件决定,如日期可能为字符串或 Date,与 uniboot-ui 行为一致)。
DialogFormFinishResult
enum
- 返回
false:不关闭当前弹层(对话框或抽屉)。 - 返回
true或undefined/ 未return:关闭当前弹层。
DialogFormOnFinish
type DialogFormOnFinish = (
values: DialogFormValues
) => Promise<DialogFormFinishResult> | DialogFormFinishResultDrawerForm(可选)
仍可从 uniboot-ui 导入 DrawerForm,等价于 <dialog-form variant="drawer" />。类型 DrawerFormField 等与 DialogFormField 相同(别名)。
DialogFormVariant
enum — DialogForm 的 variant 属性类型,由 uniboot-ui 导出。
代码片段(最小示例)
<script setup lang="ts">
import { ref } from 'vue'
import { DialogForm, UMessage } from 'uniboot-ui'
import type { DialogFormField, DialogFormValues } from 'uniboot-ui'
const visible = ref(false)
const fields: DialogFormField[] = [
{ key: 'name', label: '名称', required: true },
]
async function onFinish(values: DialogFormValues) {
try {
await fetch('/api/items', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(values),
})
UMessage.success('已保存')
return true
} catch {
UMessage.error('网络异常')
return false
}
}
</script>
<template>
<u-button type="primary" @click="visible = true">打开</u-button>
<dialog-form
v-model:visible="visible"
title="新建"
:fields="fields"
:on-finish="onFinish"
/>
</template>开发说明
实现位于 packages/components 仓库的 dialog-form;DrawerForm 在 src/drawer-form/index.ts 中复用同一实现。本地构建与文档站联调见 开发指南。