用 SchemaForm 写表单真的太爽了

511 阅读3分钟

react-admin-kit 组件库里提供了一个 SchemaForm 组件, 它本质上是封装了antd 的 proComponents. 用一个简单的对象来创建表单, 写惯了真的是太舒服了, 并且非常灵活, 在这里分享一下.

创建表单只需要一个对象数组:

const columns = [
  {
    title: '用户名',
    dataIndex: 'username'
  },
  {
    title: '密码',
    dataIndex: 'password'
  }
]

生成表单

import { SchemaForm } from 'react-admin-kit';

const Demo = () => {
  return <SchemaForm columns={columns} submitter onFinish={handleSubmit} />
}
login-form

增加必选

const columns = [
  {
    title: '用户名',
    dataIndex: 'username',
    formItemProps: { rules: [{ required: true }] }, // 传给 Form.Item 的属性
  },
  {
    title: '密码',
    dataIndex: 'password',
    formItemProps: { rules: [{ required: true }] }
  }
]
form required

给输入框增加图标

fieldProps 可以传属性给表单控件.

const columns = [
  {
    title: '用户名',
    dataIndex: 'username',
    formItemProps: { rules: [{ required: true }] }, // 传给 Form.Item 的属性
    fieldProps: { prefix: <UserOutlined /> }, // 传给表单控件的属性
  },
  {
    title: '密码',
    dataIndex: 'password',
    formItemProps: { rules: [{ required: true }] },
    fieldProps: { prefix: <LockOutlined /> },
  }
]
form fieldProps

将密码输入框改成密码框

valueType 可以指定预设的表单控件, 不指定默认是 input.

{
    title: '密码',
    dataIndex: 'password',
    formItemProps: { rules: [{ required: true }] },
    fieldProps: { prefix: <LockOutlined /> },
    valueType: 'password', // valueType 为预设的表单控件
  }
form valueType

登录框 codesandbox 链接

试试表单赋值

现在有一个关于店铺的表单, 如下:

const columns = [
    {
      title: "店铺",
      dataIndex: "shop",
      valueType: "select", // 控件是一个选择框
      formItemProps: { rules: [{ required: true }] },
      fieldProps: {
        options: [
          { label: "店铺A", value: "a", address: "北大街1号" },
          { label: "店铺B", value: "b", address: "北大街2号" },
          { label: "店铺C", value: "c", address: "北大街3号" },
        ],
      },
    },
    {
      title: "地址",
      dataIndex: "address",
    },
];
shop form

选择店铺后希望把地址自动带出来.

这时 fieldProps 可以改成一个函数, 函数参数是 form 实例, 用它可以实现赋值.

const columns = [
    {
      title: "店铺",
      dataIndex: "shop",
      valueType: "select",
      formItemProps: { rules: [{ required: true }] },
      fieldProps: (form) => {
        return {
          options: [
            { label: "店铺A", value: "a", address: "北大街1号" },
            { label: "店铺B", value: "b", address: "北大街2号" },
            { label: "店铺C", value: "c", address: "北大街3号" },
          ],
          onChange: (val, option) => {
            form.setFieldsValue({ address: option.address });
          },
        };
      },
    },
    {
      title: "地址",
      dataIndex: "address",
    },
  ];
form setFields

表单联动

现在店铺的表单又新增了两个表单项: 是否整租 和 租赁面积, 如果是否整租选择了是, 租赁面积项隐藏.

要实现表单联动可以用 valueType: dependency, name 字段里提供一个数组, 里面是需要依赖的表单项.

const columns = [
{
  title: "是否整租",
  dataIndex: "rentAll",
  valueType: "radio",
  initialValue: 0,
  fieldProps: {
    options: [
      { label: "是", value: 1 },
      { label: "否", value: 0 },
    ],
  },
},
{
  valueType: "dependency",
  name: ["rentAll"], // 需要依赖的项
  columns: ({ rentAll }) => {
    if (!rentAll) {
      return [
        {
          title: "租赁面积",
          dataIndex: "rentArea",
          valueType: "digit",
        },
      ];
    }

    return [];
  },
 },
]
form dependency

调整布局

通过 grid 属性可以开启布局, 组件内其实内置了 Row Col 组件.

<SchemaForm
  grid
  colProps={{ span: 12 }} // 一行两列
  rowProps={{ gutter: [16, 0] }} // x 方向间距 16px
/>

每个表单项也可以单独设置

{
  title: '店铺',
  dataIndex: 'shop',
  colProps: { span: 24 }
}
form grid layout

表单数组

在上面店铺表单的基础上, 甚至还能实现数组的能力.

const columns = [
 {
   dataIndex: 'shopList',
   valueType: 'formList',
   columns: [
     ... // 店铺
   ]
 }
]

有一点需要注意的是, 要实现布局能力, 店铺需要被一个 valueType: group 包裹.

const columns = [
 {
   dataIndex: 'shopList',
   valueType: 'formList',
   columns: [
     {
       valueType: 'group',
       colProps: {span: 24},
       columns: [
         ... // 店铺
       ]
     }
   ]
 }
]

form list grid

切换成只读

组件的 readonly 属性可以将整个表单切换成只读模式.

<SchemaForm readonly />

表单项也能单独设置只读模式.

{
  title: '店铺',
  dataIndex: 'shop',
  readonly: true
}
form readonly

店铺表单 codesandbox 链接

以上只是 SchemaForm 组件的部分能力, 详细请查看文档.

json 表单让创建表单变得 so 简单~~