DialogForm 对话框表单

基于 uniboot-uiUDialog / UDrawerUForm 封装的 弹层表单:通过 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,小屏单列。
drawerUDrawer透传 sizedirection;表单栅格由 columns1 | 2)控制;底部可选 footerTopBorder

两种模式下 打开重置模型finish / onFinishreturn false 不关闭loading \|\| submitting 等行为一致。文档示例均可在 对话框 / 抽屉 间切换预览。

切换 对话框 / 抽屉 后打开同一表单,提交结果用消息区分。

承载

显示与提交流程

  1. 使用 v-model:visible 控制显隐;每次 打开 时会根据 fieldsinitialValues 重置内部表单模型。
  2. 点击 确定:先走 uniboot-ui 表单校验,通过后依次 emit('finish', values)、再执行 onFinish(若传入)。
  3. onFinish 返回 falsePromise<false>不关闭 当前弹层;返回 trueundefined 或未定义返回值时 关闭(与内部 undefined 结果一致)。
  4. 确定按钮 的 loading 为 loading || submittingsubmittingonFinish 为 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 提示。

承载

初始值与编辑

initialValuesRecord<string, unknown>,键与 fields[].key 对应;未提供的键会初始化为空字符串 ''

打开即回显姓名、邮箱、部门,保存后提示成功。

承载

提交失败时保持打开

业务错误(如唯一键冲突)时 return false,弹层保持打开,便于用户修改后再次提交。

首次提交模拟冲突;再次提交成功。

承载

描述区:description 与插槽

  • description 属性:展示内置信息条样式(图标 + 文案)。
  • #description 插槽完全自定义 描述区内容;只要提供了该插槽,就不再使用 description 属性

使用 #description 自定义布局与样式。

承载

布局说明

  • variant="dialog":表单区域为 双列 CSS Gridrepeat(2, 1fr)),表单项自上而下、从左到右填充;视口宽度 ≤ 768px 时为 单列
  • variant="drawer":由 columns 控制 1 单列或 2 双列(双列时小屏同样降为单列)。
  • 某项需在双列下 独占一行 时,在该字段上设置 colSpan: 2(例如备注、长文本域)。

双列中「备注」使用 colSpan: 2 占满一行。

承载

自定义表单项:#field-{key} 插槽

当某一列需要 输入框 + 附属操作(如校验、复制、扫码)等组合布局时,可为该字段提供 #field-{key} 插槽,完全替换该项的默认控件;UFormItem 的标签与校验 prop 仍由 fields 配置,与内置渲染一致。

  • 插槽名与字段 key 对应:例如 key: 'kcv' 时使用 #field-kcvkey: 'externalKeyRef' 时使用 #field-externalKeyRef
  • 作用域参数:model 为表单响应式对象(可与 v-model="model.xxx" 双向绑定);field 为当前字段配置项。

与示意图一致:双列表单项 + KCV 行内 输入框 +「检验」主按钮(其余列仍走配置化渲染)。

承载

自定义校验

required: true 外,可通过 rules 传入与 UForm 一致的规则数组;若同时 required,内置必填规则会排在前面。

ts
import type { DialogFormField } from 'uniboot-ui'

const fields: DialogFormField[] = [
  {
    key: 'email',
    label: '邮箱',
    required: true,
    rules: [{ type: 'email', message: '请输入正确邮箱', trigger: 'blur' }],
  },
]

DialogForm 属性

名称说明类型默认值
variant承载方式:dialog 对话框,drawer 抽屉enumdialog
visible是否显示,使用 v-model:visiblebooleanfalse
title标题string标题文本
description描述文案(表单上方信息条);与 #description 插槽 互斥,有插槽时忽略属性string''
fields表单字段配置array[]
initialValues打开时的初始值object{}
loading确定按钮额外 loading(会与内部提交态叠加)booleanfalse
confirmText确定按钮文案string确定
cancelText取消按钮文案string取消
onFinish校验通过后的提交回调;返回 false 时不关闭Function
widthvariant="dialog" 时:宽度,透传 UDialogstring / number720
sizevariant="drawer" 时:尺寸,透传 UDrawerstring / number520
directionvariant="drawer" 时:打开方向,透传 UDrawerenumrtl
columnsvariant="drawer" 时:表单栅格列数 1 单列 / 2 双列enum2
footerTopBordervariant="drawer" 时:底部操作区顶部分隔线booleantrue
showClose是否显示右上角关闭按钮booleantrue

事件

名称说明类型
finish校验通过后、调用 onFinish 之前触发,参数为当前表单值Function
cancel用户取消或关闭时触发(如点击取消、关闭图标等)Function
update:visible显隐变化Function

插槽

名称说明
description自定义描述区域;存在时 不使用 description 属性
field-{key}覆盖 fields 中对应 key 的控件区(含标签);作用域参数 modelfield(见上文「自定义表单项」)
footer自定义底部操作区;未提供 时为默认「取消 + 确定」。提供插槽即 整区替换,可通过作用域参数调用提交/取消(见下表)
参数说明
submit与默认「确定」相同:校验通过后执行 finish / onFinish 及关闭逻辑
cancel与默认「取消」相同:关闭并触发 cancel 事件
loading提交中状态(loading 与内部 submitting 的合并结果),用于主按钮 loading
vue
<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
optionstype === 'select' 时的选项array
colSpan双列下横向占位:1 占半行,2 独占一行(占满整行);小屏单列时与 1 相同enum否(默认 1

DialogFormValues

表单值类型:object(各字段实际类型由控件决定,如日期可能为字符串或 Date,与 uniboot-ui 行为一致)。

DialogFormFinishResult

enum

  • 返回 false:不关闭当前弹层(对话框或抽屉)。
  • 返回 trueundefined / 未 return:关闭当前弹层。

DialogFormOnFinish

ts
type DialogFormOnFinish = (
  values: DialogFormValues
) => Promise<DialogFormFinishResult> | DialogFormFinishResult

DrawerForm(可选)

仍可从 uniboot-ui 导入 DrawerForm,等价于 <dialog-form variant="drawer" />。类型 DrawerFormField 等与 DialogFormField 相同(别名)。

DialogFormVariant

enumDialogFormvariant 属性类型,由 uniboot-ui 导出。

代码片段(最小示例)

vue
<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-formDrawerFormsrc/drawer-form/index.ts 中复用同一实现。本地构建与文档站联调见 开发指南