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。

相关推荐
SunTecTec18 分钟前
Flink Docker Application Mode 命令解析 - 修改命令以启用 Web UI
大数据·前端·docker·flink
拉不动的猪1 小时前
前端常见数组分析
前端·javascript·面试
小吕学编程2 小时前
ES练习册
java·前端·elasticsearch
Asthenia04122 小时前
Netty编解码器详解与实战
前端
袁煦丞2 小时前
每天省2小时!这个网盘神器让我告别云存储混乱(附内网穿透神操作)
前端·程序员·远程工作
一个专注写代码的程序媛3 小时前
vue组件间通信
前端·javascript·vue.js
一笑code3 小时前
美团社招一面
前端·javascript·vue.js
懒懒是个程序员3 小时前
layui时间范围
前端·javascript·layui
NoneCoder3 小时前
HTML响应式网页设计与跨平台适配
前端·html
凯哥19704 小时前
在 Uni-app 做的后台中使用 Howler.js 实现强大的音频播放功能
前端