Form 表单组件
对 antv 的 form 组件进行封装,扩展一些常用的功能
如果文档内没有,可以尝试在在线示例内寻找
Usage
useForm 方式
下面是一个使用简单表单的示例,只有一个输入框
<template> <div class="m-4"> <BasicForm :labelWidth="100" :schemas="schemas" :actionColOptions="{ span: 24 }" @submit="handleSubmit" /> </div></template><script lang="ts"> import { defineComponent } from 'vue'; import { BasicForm, FormSchema } from '/@/components/Form'; import { CollapseContainer } from '/@/components/Container'; import { useMessage } from '/@/hooks/web/useMessage'; const schemas: FormSchema[] = [ { field: 'field', component: 'Input', label: '字段1', colProps: { span: 8, }, defaultValue: '1', componentProps: { placeholder: '自定义placeholder', onChange: (e) => { console.log(e); }, }, }, ];
export default defineComponent({ components: { BasicForm, CollapseContainer }, setup() { const { createMessage } = useMessage(); return { schemas, handleSubmit: (values: any) => { createMessage.success('click search,values:' + JSON.stringify(values)); }, }; }, });</script>template 方式
所有可调用函数见下方 Methods 说明
<template> <div class="m-4"> <BasicForm :schemas="schemas" ref="formElRef" :labelWidth="100" @submit="handleSubmit" :actionColOptions="{ span: 24 }" /> </div></template><script lang="ts"> import { defineComponent, ref } from 'vue'; import { BasicForm, FormSchema, FormActionType, FormProps } from '/@/components/Form'; import { CollapseContainer } from '/@/components/Container'; const schemas: FormSchema[] = [];
export default defineComponent({ components: { BasicForm, CollapseContainer }, setup() { const formElRef = ref<Nullable<FormActionType>>(null); return { formElRef, schemas, setProps(props: FormProps) { const formEl = formElRef.value; if (!formEl) return; formEl.setProps(props); }, }; }, });</script>useForm
form 组件还提供了 useForm,方便调用函数内部方法
示例
<template> <BasicForm @register="register" @submit="handleSubmit" /></template><script lang="ts"> import { defineComponent } from 'vue'; import { BasicForm, FormSchema, useForm } from '/@/components/Form/index'; import { CollapseContainer } from '/@/components/Container/index'; import { useMessage } from '/@/hooks/web/useMessage'; const schemas: FormSchema[] = [ { field: 'field1', component: 'Input', label: '字段1', colProps: { span: 8, }, componentProps: { placeholder: '自定义placeholder', onChange: (e: any) => { console.log(e); }, }, }, ];
export default defineComponent({ components: { BasicForm, CollapseContainer }, setup() { const { createMessage } = useMessage(); const [register, { setProps }] = useForm({ labelWidth: 120, schemas, actionColOptions: { span: 24, }, }); return { register, schemas, handleSubmit: (values: any) => { createMessage.success('click search,values:' + JSON.stringify(values)); }, setProps, }; }, });</script>参数介绍
const [register, methods] = useForm(props);参数 props 内的值可以是 computed 或者 ref 类型
register
register 用于注册 useForm,如果需要使用 useForm 提供的 api,必须将 register 传入组件的 onRegister
<template> <BasicForm @register="register" @submit="handleSubmit" /></template><script> export default defineComponent({ components: { BasicForm }, setup() { const [register] = useForm(); return { register, }; }, });</script>Methods见下方说明
Methods
getFieldsValue
类型: () => Recordable;
说明: 获取表单值
setFieldsValue
类型: <T>(values: T) => Promise<void>
说明: 设置表单字段值
resetFields
类型: ()=> Promise<void>
说明: 重置表单值
validateFields
类型: (nameList?: NamePath[]) => Promise<any>
说明: 校验指定表单项
validate
类型: (nameList?: NamePath[]) => Promise<any>
说明: 校验整个表单
submit
类型: () => Promise<void>
说明: 提交表单
scrollToField
类型: (name: NamePath, options?: ScrollOptions) => Promise<void>
说明: 滚动到对应字段位置
clearValidate
类型: (name?: string | string[]) => Promise<void>
说明: 清空校验
setProps
类型: (formProps: Partial<FormProps>) => Promise<void>
说明: 设置表单 Props
removeSchemaByField
类型: (field: string | string[]) => Promise<void>
说明: 根据 field 删除 Schema
appendSchemaByField
类型: ( schema: FormSchema, prefixField: string | undefined, first?: boolean | undefined ) => Promise<void>
说明: 插入到指定 filed 后面,如果没传指定 field,则插入到最后,当 first = true 时插入到第一个位置
updateSchema
类型: (data: Partial<FormSchema> | Partial<FormSchema>[]) => Promise<void>
说明: 更新表单的 schema, 只更新函数所传的参数
e.g
updateSchema({ field: 'filed', componentProps: { disabled: true } });updateSchema([ { field: 'filed', componentProps: { disabled: true } }, { field: 'filed1', componentProps: { disabled: false } },]);Props
| 属性 | 类型 | 默认值 | 可选值 | 说明 | 版本 |
|---|---|---|---|---|---|
| schemas | Schema[] | - | - | 表单配置,见下方 FormSchema 配置 | |
| submitOnReset | boolean | false | - | 重置时是否提交表单 | |
| labelCol | Partial<ColEx> | - | - | 整个表单通用 LabelCol 配置 | |
| wrapperCol | Partial<ColEx> | - | - | 整个表单通用 wrapperCol 配置 | |
| baseColProps | Partial<ColEx> | - | - | 配置所有选子项的 ColProps,不需要逐个配置,子项也可单独配置优先与全局 | |
| baseRowStyle | object | - | - | 配置所有 Row 的 style 样式 | |
| labelWidth | number , string | - | - | 扩展 form 组件,增加 label 宽度,表单内所有组件适用,可以单独在某个项覆盖或者禁用 | |
| labelAlign | string | - | left,right | label 布局 | |
| mergeDynamicData | object | - | - | 额外传递到子组件的参数 values | |
| autoFocusFirstItem | boolean | false | - | 是否聚焦第一个输入框,只在第一个表单项为 input 的时候作用 | |
| compact | boolean | false | true/false | 紧凑类型表单,减少 margin-bottom | |
| size | string | default | 'default' , 'small' , 'large' | 向表单内所有组件传递 size 参数,自定义组件需自行实现 size 接收 | |
| disabled | boolean | false | true/false | 向表单内所有组件传递 disabled 属性,自定义组件需自行实现 disabled 接收 | |
| autoSetPlaceHolder | boolean | true | true/false | 自动设置表单内组件的 placeholder,自定义组件需自行实现 | |
| autoSubmitOnEnter | boolean | false | true/false | 在 input 中输入时按回车自动提交 | 2.4.0 |
| rulesMessageJoinLabel | boolean | false | true/false | 如果表单项有校验,会自动生成校验信息,该参数控制是否将字段中文名字拼接到自动生成的信息后方 | |
| showAdvancedButton | boolean | false | true/false | 是否显示收起展开按钮 | |
| emptySpan | number , Partial<ColEx> | 0 | - | 空白行格,可以是数值或者 col 对象 数 | |
| autoAdvancedLine | number | 3 | - | 如果 showAdvancedButton 为 true,超过指定行数行默认折叠 | |
| alwaysShowLines | number | 1 | - | 折叠时始终保持显示的行数 | 2.7.1 |
| showActionButtonGroup | boolean | true | true/false | 是否显示操作按钮(重置/提交) | |
| actionColOptions | Partial<ColEx> | - | - | 操作按钮外层 Col 组件配置,如果开启 showAdvancedButton,则不用设置,具体见下方 actionColOptions | |
| showResetButton | boolean | true | - | 是否显示重置按钮 | |
| resetButtonOptions | object | - | 重置按钮配置见下方 ActionButtonOption | ||
| showSubmitButton | boolean | true | - | 是否显示提交按钮 | |
| submitButtonOptions | object | - | 确认按钮配置见下方 ActionButtonOption | ||
| resetFunc | () => Promise<void> | - | 重置表单行为前执行自定义重置按钮逻辑() => Promise<void>; | ||
| submitFunc | () => Promise<void> | - | 自定义提交按钮逻辑() => Promise<void>; | ||
| fieldMapToTime | [string, [string, string], string?][] | ’timestamp’ ,‘timestampStartDay’ ,momentjs 时间格式 | 用于将表单内时间区域的应设成 2 个字段,见下方说明 |
ColEx
见src/components/Form/src/types/index.ts
ActionButtonOption
export const buttonProps = { color: { type: String as PropType<ButtonColorType>, validator: (v) => validColors.includes(v), default: '', }, loading: { type: Boolean }, disabled: { type: Boolean }, /** * Text before icon. */ preIcon: { type: String }, /** * Text after icon. */ postIcon: { type: String }, /** * preIcon and postIcon icon size. * @default: 14 */ iconSize: { type: Number, default: 14 }, onClick: { type: [Function, Array] as PropType<(() => any) | (() => any)[]>, default: null },
/** * 如果需要修改默认内置的重置、提交按钮的文本,可以传递这个属性,可选属性 */ text: { type: String },};fieldMapToTime
将表单内时间区域的值映射成 2 个字段
如果表单内有时间区间组件,获取到的值是一个数组,但是往往我们传递到后台需要是 2 个字段
useForm({ fieldMapToTime: [ // data为时间组件在表单内的字段,startTime,endTime为转化后的开始时间与结束时间 // 'YYYY-MM-DD'为时间格式,参考moment ['datetime', ['startTime', 'endTime'], 'YYYY-MM-DD'], // 支持多个字段 ['datetime1', ['startTime1', 'endTime1'], 'YYYY-MM-DD HH:mm:ss'], ],});
// fieldMapToTime没写的时候表单获取到的值{ datetime: [Date(),Date()]}// ['datetime', ['startTime', 'endTime'], 'YYYY-MM-DD'],等同于 dayjs(Date()).format('YYYY-MM-DD'). 之后{ startTime: '2020-08-12', endTime: '2020-08-15',}
// ['datetime', ['startTime', 'endTime'], 'timestamp'],等同于 dayjs(Date()).unix(). 之后{ startTime: 1597190400, endTime: 1597449600,}
// ['datetime', ['startTime', 'endTime'], 'timestampStartDay'],等同于 dayjs(Date()).startOf('day').unix(). 之后{ startTime: 1597190400, endTime: 1597449600,}FormSchema
| 属性 | 类型 | 默认值 | 可选值 | 说明 |
|---|---|---|---|---|
| field | string | - | - | 字段名 |
| label | string | - | - | 标签名 |
| subLabel | string | - | - | 二级标签名灰色 |
| suffix | string , number , ((values: RenderCallbackParams) => string / number); | - | - | 组件后面的内容 |
| changeEvent | string | - | - | 表单更新事件名称 |
| helpMessage | string , string[] | - | - | 标签名右侧温馨提示 |
| helpComponentProps | HelpComponentProps | - | - | 标签名右侧温馨提示组件 props,见下方 HelpComponentProps |
| labelWidth | string , number | - | - | 覆盖统一设置的 labelWidth |
| disabledLabelWidth | boolean | false | true/false | 禁用 form 全局设置的 labelWidth,自己手动设置 labelCol 和 wrapperCol |
| component | string | - | - | 组件类型,见下方 ComponentType |
| componentProps | any,()=>{} | - | - | 所渲染的组件的 props |
| rules | ValidationRule[] | - | - | 校验规则,见下方 ValidationRule |
| required | boolean | - | - | 简化 rules 配置,为 true 则转化成 [{required:true}]。2.4.0之前的版本只支持 string 类型的值 |
| rulesMessageJoinLabel | boolean | false | - | 校验信息是否加入 label |
| itemProps | any | - | - | 参考下方 FormItem |
| colProps | ColEx | - | - | 参考上方 actionColOptions |
| defaultValue | object | - | - | 所渲渲染组件的初始值 |
| render | (renderCallbackParams: RenderCallbackParams) => VNode / VNode[] / string | - | - | 自定义渲染组件 |
| renderColContent | (renderCallbackParams: RenderCallbackParams) => VNode / VNode[] / string | - | - | 自定义渲染组件(需要自行包含 formItem) |
| renderComponentContent | (renderCallbackParams: RenderCallbackParams) => any / string | - | - | 自定义渲染组内部的 slot |
| slot | string | - | - | 自定义 slot,渲染组件 |
| colSlot | string | - | - | 自定义 slot,渲染组件 (需要自行包含 formItem) |
| show | boolean / ((renderCallbackParams: RenderCallbackParams) => boolean) | - | - | 动态判断当前组件是否显示,css 控制,不会删除 dom |
| ifShow | boolean / ((renderCallbackParams: RenderCallbackParams) => boolean) | - | - | 动态判断当前组件是否显示,js 控制,会删除 dom |
| dynamicDisabled | boolean / ((renderCallbackParams: RenderCallbackParams) => boolean) | - | - | 动态判断当前组件是否禁用 |
| dynamicRules | boolean / ((renderCallbackParams: RenderCallbackParams) => boolean) | - | - | 动态判返当前组件你校验规则 |
RenderCallbackParams
export interface RenderCallbackParams { schema: FormSchema; values: any; model: any; field: string;}componentProps
-
当值为对象类型时,该对象将作为
component所对应组件的的 props 传入组件 -
当值为一个函数时候
参数有 4 个
schema: 表单的整个 schemas
formActionType: 操作表单的函数。与 useForm 返回的操作函数一致
formModel: 表单的双向绑定对象,这个值是响应式的。所以可以方便处理很多操作
tableAction: 操作表格的函数,与 useTable 返回的操作函数一致。注意该参数只在表格内开启搜索表单的时候有值,其余情况为null,
{ // 简单例子,值改变的时候操作表格或者修改表单内其他元素的值 component:'Input', componentProps: ({ schema, tableAction, formActionType, formModel }) => { return { // xxxx props onChange:(e)=>{ const {reload}=tableAction reload() // or formModel.xxx='123' } }; };}HelpComponentProps
export interface HelpComponentProps { maxWidth: string; // 是否显示序号 showIndex: boolean; // 文本列表 text: any; // 颜色 color: string; // 字体大小 fontSize: string; icon: string; absolute: boolean; // 定位 position: any;}ComponentType
schema 内组件的可选类型
export type ComponentType = | 'Input' | 'InputGroup' | 'InputPassword' | 'InputSearch' | 'InputTextArea' | 'InputNumber' | 'InputCountDown' | 'Select' | 'ApiSelect' | 'TreeSelect' | 'RadioButtonGroup' | 'RadioGroup' | 'Checkbox' | 'CheckboxGroup' | 'AutoComplete' | 'Cascader' | 'DatePicker' | 'MonthPicker' | 'RangePicker' | 'WeekPicker' | 'TimePicker' | 'Switch' | 'StrengthMeter' | 'Upload' | 'IconPicker' | 'Render' | 'Slider' | 'Rate' | 'Divider'; // v2.7.2新增Divider schema 说明
Divider类型用于在schemas中占位,将会渲染成一个分割线(始终占一整行的版面),可以用于较长表单的版面分隔。请只将 Divider 类型的 schema 当作一个分割线,而不是一个常规的表单字段。
Divider仅在showAdvancedButton为 false 时才会显示(也就是说如果启用了表单收起和展开功能,Divider将不会显示)Divider使用schema中的label以及helpMessage来渲染分割线中的提示内容Divider可以使用componentProps来设置除type之外的 propsDivider不会渲染AFormItem,因此schema中除label、componentProps、helpMessage、helpComponentProps以外的属性不会被用到
自行添加需要的组件类型
在 src/components/Form/src/componentMap.ts 内,添加需要的组件,并在上方 ComponentType 添加相应的类型 key
方式 1
这种写法适用与适用频率较高的组件
componentMap.set('componentName', 组件);
// ComponentTypeexport type ComponentType = xxxx | 'componentName';方式 2
使用 useComponentRegister 进行注册
这种写法只能在当前页使用,页面销毁之后会从 componentMap 删除相应的组件
import { useComponentRegister } from '@/components/form/index';
import { StrengthMeter } from '@/components/strength-meter/index';
useComponentRegister('StrengthMeter', StrengthMeter);render
自定义渲染内容
<template> <div class="m-4"> <BasicForm @register="register" @submit="handleSubmit" /> </div></template><script lang="ts"> import { defineComponent, h } from 'vue'; import { BasicForm, FormSchema, useForm } from '/@/components/Form/index'; import { useMessage } from '/@/hooks/web/useMessage'; import { Input } from 'cosine-fee'; const schemas: FormSchema[] = [ { field: 'field1', component: 'Input', label: '字段1', colProps: { span: 8, }, rules: [{ required: true }], render: ({ model, field }) => { return h(Input, { placeholder: '请输入', value: model[field], onChange: (e: ChangeEvent) => { model[field] = e.target.value; }, }); }, }, { field: 'field2', component: 'Input', label: '字段2', colProps: { span: 8, }, rules: [{ required: true }], renderComponentContent: () => { return { suffix: () => 'suffix', }; }, }, ]; export default defineComponent({ components: { BasicForm }, setup() { const { createMessage } = useMessage(); const [register, { setProps }] = useForm({ labelWidth: 120, schemas, actionColOptions: { span: 24, }, }); return { register, schemas, handleSubmit: (values: any) => { createMessage.success('click search,values:' + JSON.stringify(values)); }, setProps, }; }, });</script>slot
自定义渲染内容
<template> <div class="m-4"> <BasicForm @register="register"> <template #customSlot="{ model, field }"> <a-input v-model:value="model[field]" /> </template> </BasicForm> </div></template><script lang="ts"> import { defineComponent } from 'compatible-vue'; import { BasicForm, useForm } from '@/components/Form/index'; import { BasicModal } from '@/components/modal/index'; export default defineComponent({ name: 'FormDemo', setup(props) { const [register] = useForm({ labelWidth: 100, actionColOptions: { span: 24, }, schemas: [ { field: 'field1', label: '字段1', slot: 'customSlot', }, ], }); return { register, }; }, });</script>ifShow/show/dynamicDisabled
自定义显示/禁用
<template> <div class="m-4"> <BasicForm @register="register" /> </div></template><script lang="ts"> import { defineComponent } from 'vue'; import { BasicForm, FormSchema, useForm } from '/@/components/Form/index'; const schemas: FormSchema[] = [ { field: 'field1', component: 'Input', label: '字段1', colProps: { span: 8, }, show: ({ values }) => { return !!values.field5; }, }, { field: 'field2', component: 'Input', label: '字段2', colProps: { span: 8, }, ifShow: ({ values }) => { return !!values.field6; }, }, { field: 'field3', component: 'DatePicker', label: '字段3', colProps: { span: 8, }, dynamicDisabled: ({ values }) => { return !!values.field7; }, }, ];
export default defineComponent({ components: { BasicForm }, setup() { const [register, { setProps }] = useForm({ labelWidth: 120, schemas, actionColOptions: { span: 24, }, }); return { register, schemas, setProps, }; }, });</script>Slots
| 名称 | 说明 |
|---|---|
| formFooter | 表单底部区域 |
| formHeader | 表单顶部区域 |
| resetBefore | 重置按钮前 |
| submitBefore | 提交按钮前 |
| advanceBefore | 展开按钮前 |
| advanceAfter | 展开按钮后 |
ApiSelect
远程下拉加载组件,该组件可以用于学习参考如何自定义组件集成到 Form 组件内,将自定义组件交由 Form 去管理
Usage
const schemas: FormSchema[] = [ { field: 'field', component: 'ApiSelect', label: '字段', },];Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| numberToString | boolean | false | 是否将number值转化为string |
| api | ()=>Promise<{ label: string; value: string; disabled?: boolean }[]> | - | 数据接口,接受一个 Promise 对象 |
| params | object | - | 接口参数。此属性改变时会自动重新加载接口数据 |
| resultField | string | - | 接口返回的字段,如果接口返回数组,可以不填。支持x.x.x格式 |
| labelField | string | label | 下拉数组项内label显示文本的字段,支持x.x.x格式 |
| valueField | string | value | 下拉数组项内value实际值的字段,支持x.x.x格式 |
| immediate | boolean | true | 是否立即请求接口,否则将在第一次点击时候触发请求 |
ApiTreeSelect
远程下拉树加载组件,和ApiSelect类似,2.6.1 以上版本
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| api | ()=>Promise<{ label: string; value: string; children?: any[] }[]> | - | 数据接口,接受一个 Promise 对象 |
| params | object | - | 接口参数。此属性改变时会自动重新加载接口数据 |
| resultField | string | - | 接口返回的字段,如果接口返回数组,可以不填。支持x.x.x格式 |
| immediate | boolean | true | 是否立即请求接口。 |
RadioButtonGroup
Radio Button 风格的选择按钮
Usage
const schemas: FormSchema[] = [ { field: 'field', component: 'RadioButtonGroup', label: '字段', },];Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| options | { label: string; value: string; disabled?: boolean }[] | - | 数据字段 |