Appearance
FForm 配置化表单
FForm 是基于 Vue 3 与 Element Plus 的配置化表单组件,支持字段注册表、响应式联动、分区、脏状态、异步校验、提交状态和值转换。
使用组件
FForm。字段配置统一使用schemas、field、component和F前缀内置组件名。
使用方式
Hooks 模式
useForm 返回 [register, methods]。@register 的作用是把已挂载的 FForm 实例交给 methods,并不是触发表单渲染;忘记绑定时表单仍可渲染,但 Hook 方法没有可操作的实例。
vue
<template>
<FForm @register="register" @submit="handleSubmit" />
</template>
<script setup lang="ts">
import { FForm, useForm } from '@axewo/fin-ui'
const [register, methods] = useForm({
schemas: [
{ field: 'name', label: '姓名', component: 'FInput', required: true },
{ field: 'age', label: '年龄', component: 'FInputNumber' },
],
actions: { submit: '提交', reset: '重置' },
})
function handleSubmit(values: Record<string, any>) {
console.log(values)
}
</script>在组件挂载后(例如事件处理函数或 onMounted 中)调用 methods。每个表单应使用独立的 useForm 实例。
Props 模式
vue
<template>
<FForm v-model="formData" :config="formConfig" @submit="handleSubmit" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { FForm, type UseFormProps } from '@axewo/fin-ui'
const formData = ref({ name: '', age: 18 })
const formConfig: UseFormProps = {
schemas: [
{ field: 'name', label: '姓名', component: 'FInput' },
{ field: 'age', label: '年龄', component: 'FInputNumber' },
],
}
function handleSubmit(values: Record<string, any>) {
console.log(values)
}
</script>config 可响应式更新;新的 schemas、sections、mode、scene 和 syncMode 会同步到表单内部。配置类型为 UseFormProps,普通字段使用 schemas,分区字段使用 sections[].items。
示例
loading
loading
loading
loading
loading
loading
loading
loading
loading
loading
配置语义
schemas 与 sections
schemas定义普通表单的字段。- 设置非空
sections后进入分区模式,字段由各分区的items提供,schemas不参与渲染和提交。 section.hidden可传布尔值或(values) => boolean;collapsed当前仅为配置字段,不负责折叠交互。
重置与脏状态
表单会为当前值建立基线快照:初次初始化(包含 defaultValue)建立初始基线,父组件外部回填新的 v-model 值会建立新基线。字段编辑后 isDirty 变为 true。
resetFields():恢复基线并清除校验;无论syncMode为何,重置值都会立即同步给父组件。takeSnapshot():把当前值设为新的已保存基线。resetToSnapshot():直接恢复当前基线,适合自定义操作栏。- Schema 更新只会为新增且尚无值的字段补
defaultValue,不会覆盖未保存编辑,也不会整体重建基线。
syncMode
| 值 | update:modelValue 时机 |
|---|---|
realtime | 字段变化后(默认) |
blur | 字段失焦时 |
submit | 校验通过并提交时 |
程序调用 setFieldsValue() 仍会更新内部模型并参与脏状态比较;重置始终立即向外同步。
reactions
每条联动配置必须声明 dependencies:
handler(values, schema)派生当前字段的 Schema(例如ifShow、disabled);只有依赖值均非空时执行。setOptions(values)可同步或异步返回当前字段的新选项;后发请求优先,旧异步结果不会覆盖新结果。resetFields在依赖值实际变化后清空指定字段;初始化监听不会误清空已有值。
ts
{
field: 'account',
component: 'FSelect',
reactions: [{
dependencies: ['voucherType'],
setOptions: values => accountOptions[values.voucherType] ?? [],
resetFields: ['account'],
}],
}FormSchema 常用配置
| 属性 | 类型 | 说明 |
|---|---|---|
field | string | 必填,模型中的唯一字段名 |
label | string | 表单项标签 |
component | string | Component | 注册表名称或 Vue 组件,默认按 F 前缀书写 |
componentProps | object | (params) => object | 透传给字段组件的属性 |
colProps / span | ColProps / number | 栅格配置与简写 |
defaultValue | any | 字段没有值时使用的默认值 |
required / rules | boolean | string / FormRule[] | 必填简写与字段自定义规则;集中合并至父级 ElForm.rules |
asyncValidator | (value, values) => Promise<string | null> | FormRule 的异步校验简写,返回错误信息或 null |
ifShow | boolean | (params) => boolean | 是否渲染字段 |
disabled | boolean | 静态禁用 |
dynamicDisabled | (params) => boolean | 动态禁用 |
options | FieldOption[] | () => Promise<FieldOption[]> | 静态或异步选项 |
transform | (value, values) => any | 仅转换提交结果,不改写表单模型 |
reactions | FieldReaction[] | 字段联动 |
render | (params: FormFieldRenderParams) => VNodeChild | 完整接管表单项内部内容,支持文本、VNode 与组件 VNode |
slotName | string | 字段具名插槽名称,默认使用 field |
自定义字段内容
render 与字段具名插槽都可以完整接管 ElFormItem 内部内容,但字段仍保留在表单模型、校验和提交数据中。两者在编辑与查看模式下都生效:配置了 schema.render 时,以 render 为准,具名插槽不生效。render 返回 undefined 时直接恢复当前模式的标准渲染;返回 null 或空字符串仍表示有意渲染为空,不会回退。未配置 render 时才尝试具名插槽;空插槽(例如仅转发、没有实际内容)不会阻止标准渲染。
例如编辑时下拉框使用后端编码,查看时展示后端返回的名称:
ts
{
field: 'statusCode',
component: 'FSelect',
options: statusOptions,
render: ({ mode, model }) =>
mode === 'view' ? model.statusName || '--' : undefined,
}此时编辑模式仍由 FSelect 绑定 statusCode,查看模式只展示 statusName,不会改写模型中的编码。
ts
import { h } from 'vue'
import { ElTag } from 'element-plus'
const schemas = [
{
field: 'creator',
label: '创建人',
render: ({ value }) => value || '--',
},
{
field: 'status',
label: '状态',
render: ({ value }) => h(ElTag, null, () => value),
},
{
field: 'approved',
label: '审核结果',
render: ({ value, setValue }) =>
h('button', { type: 'button', onClick: () => setValue(!value) }, value ? '已通过' : '未通过'),
},
]回调参数还包含 model、schema、schemas、scene、mode、options、componentProps、disabled 和 formActionType。仅当字段未配置 render 时,才使用父组件提供的与 slotName || field 同名的插槽;插槽接收相同上下文:
vue
<FForm :config="formConfig">
<template #creator="{ value, mode }">
<span>{{ value }}({{ mode }})</span>
</template>
</FForm>查看模式的多语言与数据字典
设置 mode: 'view' 时,FLangInput 会按照当前界面语言从多语言对象中选取文本;当前语言没有值时依次回退中文和首个非空翻译。FDictSelect、FDictRadio 则展示字典项的 label,而不是存储在模型中的编码:可通过 dictType 读取 FinConfigProvider 提供的静态字典或异步加载结果;componentProps.fieldNames 可指定字典字段映射。字段的 componentProps.options、options 优先于全局字典。字典项暂未加载或无法匹配时展示原始值。
ts
const formConfig: UseFormProps = {
mode: 'view',
schemas: [
{ field: 'name', label: '名称', component: 'FLangInput' },
{ field: 'status', label: '状态', component: 'FDictSelect', dictType: 'status' },
],
}需要完全自定义某个字段的只读内容时,仍可配置 render 或具名插槽。
自定义校验规则
字段 schema.rules 与表单级 config.rules[field] 都支持 Element Plus 标准规则(例如 pattern、type、validator、trigger),同一字段按 required 简写、表单级规则、字段规则的顺序执行,不会相互覆盖。字段也可使用 asyncValidator(value, formValues),返回错误字符串表示失败,返回 null 表示通过。
ts
const formConfig: UseFormProps = {
rules: {
email: [{ type: 'email', message: '邮箱格式不正确', trigger: 'blur' }],
},
schemas: [
{
field: 'email',
component: 'FInput',
required: '请输入邮箱',
rules: [
{
validator: (_rule, value, callback) =>
callback(value.includes('@example.com') ? undefined : new Error('请使用公司邮箱')),
},
],
},
],
}规则统一挂载到父级 ElForm;字段渲染器只设置 ElFormItem.prop 进行关联,不在 ElFormItem 上重复绑定 rules。查看模式不执行表单校验。
FormMethods API
ts
const [register, methods] = useForm(config)| 方法 | 返回值 | 说明 |
|---|---|---|
getFieldsValue() | Record<string, any> | 获取当前值 |
setFieldsValue(values) | void | 部分更新字段值 |
resetFields() | Promise<void> | 恢复基线并清除校验 |
validate() | Promise<void> | 校验全部字段;失败时 reject |
validateFields(names?) | Promise<void> | 校验指定字段;失败时 reject |
clearValidate(names?) | Promise<void> | 清除校验状态 |
submit() | Promise<void> | 触发表单提交流程 |
scrollToField(name) | void | 滚动到字段 |
setProps(props) | Promise<void> | 更新表单配置 |
updateSchema(data) | Promise<void> | 按 field 增量更新 Schema |
appendSchemaByField(schema, afterField?, first?) | Promise<void> | 添加字段 |
removeSchemaByField(fields) | Promise<void> | 删除字段 |
watchField(field, callback, options?) | () => void | 监听字段并返回停止函数 |
setMode(mode) | void | 切换 edit / view |
响应式状态包括 formModel、isDirty、submitting、isCollapsed 和 mode。它们在 useForm 返回值上是 Ref;模板会自动解包,脚本中读取状态请使用 .value。
内置组件与扩展
实际内置字段类型和自定义注册方式见: