Antd Procomponent 之 proForm - 高级表单

ProForm 在原来的 Form 基础上增加一些语法糖和更多的布局设置,帮助我们快速的开发一个表单。同时添加一些默认行为,让我们的表单默认好用。分步表单,Modal 表单,Drawer 表单,查询表单,轻量筛选等多种 layout 可以覆盖大部分的使用场景,脱离复杂而且繁琐的表单布局工作,更少的代码完成更多的功能。

ProForm 高级表单

  • 使用 initialValues设置默认值。
  • 可以使用 ProFormDependency 实现表单联动或者做一些依赖。
  • ProForm 的 onFinish 是个 Promise。
  • 使用 onValuesChange 监听某个值。
  • 如果要使用自定义的组件可以用 Form.Item 包裹后使用,支持与 antd 的 Form混用。
ini 复制代码
// 设置整体默认值
<ProForm initialValues={obj} />
​
// 设置单个控件的
<ProForm onValuesChange={(changeValues) => console.log(changeValues)}>
  <ProFormText initialValue="prop"/>
</ProForm>
​
// 相互依赖的组件联动
<ProForm>
  <ProFormDependency name={['name']}>
  {({ name }) => {
    return (
      <ProFormSelect
        options={[
          {
            value: 'chapter',
            label: '盖章后生效',
          },
        ]}
        width="md"
        name="useMode"
        label={`与《${name}》合同约定生效方式`}
      />
    )
  }}
</ProFormDependency>
</ProForm>
​
​
// 使用自定义组件
<ProForm>
  <Form.Item name="switch" label="Switch" valuePropName="checked">
    <Switch />
  </Form.Item>
</ProForm>

ProFormFields 表单项

ProFormFields 表单项本质上是 Form.Item 和 组件的结合,每个表单项都支持 fieldProps

ProFormText 是 FormItem + Input 的产物,可以类比于以下的代码:

javascript 复制代码
const ProFormText = (props) => {
  return (
    <ProForm.Item {...props}>
      <Input placeholder={props.placeholder} {...props.fieldProps} />
    </ProForm.Item>
  )
}

组件列表

ProFormList 数据结构化

  • ProFormList 录入结构化的多维数组数据。
  • ProFormFieldSet 录入结构化的一维数组数据。
  • ProFormDependency 数据依赖的相关组件

ProFormList

ProFormList 与 Form.List API 基本相同,自带操作按钮:删除和复制和新增按钮

ProFormList API

actionRef 操作 & actionGuard 拦截器

typescript 复制代码
const actionRef = useRef<FormListActionType<{ name: string }>>();
​
const actionGuard = {
  beforeAddRow: async (defaultValue, insertIndex, count) => {
    return new Promise((resolve) => {
      console.log(defaultValue?.name, insertIndex, count);
      setTimeout(() => resolve(true), 1000);
    });
  },
  beforeRemoveRow: async (index, count) => {
    const row = actionRef.current?.get(index as number);
    console.log('--->', index, count, row);
    return new Promise((resolve) => {
      if (index === 0) {
        resolve(false);
        return;
      }
      setTimeout(() => resolve(true), 1000);
    });
  },
};
​
return (
  /**
   * @name 获取到 list 操作实例
   * @description 可用删除,新增,移动等操作
   *
   * @example  actionRef?.current.add?.({},1);
   * @example  actionRef?.current.remove?.(1);
   * @example  actionRef?.current.move?.(1,2);
   * @example  actionRef?.current.get?.(1);
   */
  <>
    <Space>
      <Button
        type="primary"
        onClick={() => {
          const list = actionRef.current?.getList();
          actionRef.current?.add({
            name: '新增' + list?.length,
          });
        }}
      >
        增加一行
      </Button>
      <Button
        danger
        onClick={() => {
          actionRef.current?.remove(1);
        }}
      >
        删除一行
      </Button>
      <Button
        onClick={() => {
          actionRef.current?.move(1, 0);
        }}
      >
        移动到第一行
      </Button>
      <Button
        type="dashed"
        onClick={() => {
          const row = actionRef.current?.get(1);
          console.log(row);
        }}
      >
        获取一行数据
      </Button>
      <Button
        type="dashed"
        onClick={() => {
          const row = actionRef.current?.getList();
          console.log(row);
        }}
      >
        获取所有数据
      </Button>
    </Space>
    <ProFormList actionGuard={actionGuard} actionRef={actionRef}>
      <ProFormText key="useMode" name="name" label="姓名" />
    </ProFormList>
  </>
)

ProFormFieldSet

ProFormFieldSet 可以将内部的多个 children 的值组合并且存储在 ProForm 中

ini 复制代码
<ProFormFieldSet
  name="list"
  label="组件列表"
  // 支持 两种方式,type="group" 会用input.group 包裹
  // 如果不配置 默认使用 space
  type="group"
  transform={(value: any) => ({ startTime: value[0], endTime: value[1] })}
>
  <ProFormText width="md" />
  <ProFormText width="md" />
  <ProFormText width="md" />
</ProFormFieldSet>

ProFormDependency

ProFormDependency 是一个简化版本的 Form.Item,它默认内置了 noStyle 与 shouldUpdate,我们只需要配置 name 来确定我们依赖哪个数据,ProFormDependency 会自动处理 diff 和并且从表单中提取相应的值

name 参数必须要是一个数组,如果是嵌套的结构可以这样配置 name={['name', ['name2', 'text']]}。配置的 name 的值会在 renderProps 中传入。name={['name', ['name2', 'text']]} 传入的 values 的值 为 { name: string,name2: { text:string } }

ini 复制代码
<ProFormDependency name={['name']}>
  {({ name }) => {
    return (
      <ProFormSelect
        options={[
          {
            value: 'chapter',
            label: '盖章后生效',
          },
        ]}
        width="md"
        name="useMode"
        label={`与《${name}》合同约定生效方式`}
      />
    );
  }}
</ProFormDependency>

补充:ProForm 和 EditableTable 可以同时使用

注意: ProComponents 专注于中后台的 CRUD, 预设了相当多的样式和行为。这些行为和样式更改起来会比较困难,如果你的业务需要丰富的自定义建议直接使用 Ant Design。

相关推荐
慕斯策划一场流浪18 分钟前
fastGPT—前端开发获取api密钥调用机器人对话接口(HTML实现)
前端·html·fastgpt·fastgpt创建工作流·fastgpt创建密钥调用接口
碧海饮冰21 分钟前
前端:v-html和v-text在使用上的区别
前端·javascript·html
好_快27 分钟前
Lodash源码阅读-cloneBuffer
前端·javascript·源码阅读
好_快29 分钟前
Lodash源码阅读-initCloneArray
前端·javascript·源码阅读
好_快31 分钟前
Lodash源码阅读-get
前端·javascript·源码阅读
好_快33 分钟前
Lodash源码阅读-stringToPath
前端·javascript·源码阅读
好_快35 分钟前
Lodash源码阅读-baseGet
前端·javascript·源码阅读
我是小路路呀2 小时前
vue开始时间小于结束时间,时间格式:年月日时分
前端·javascript·vue.js
虾球xz2 小时前
游戏引擎学习第201天
前端·学习·游戏引擎
我自纵横20232 小时前
JavaScript 中常见的鼠标事件及应用
前端·javascript·css·html·计算机外设·ecmascript