Form.List和Table组件实现一个可编辑表格

1,919 阅读2分钟

Form.List

如何用antd的Form.List配合Table组件实现一个可编辑表格

快速访问

版本说明

Antd 4.X

Form.List快速访问 Table快速访问

实现思路

  1. Form.List 实现列表化的能力,布局排版使用 Table组件
  2. 在渲染Table的每一列的内容上使用render自定义渲染表单项
  3. Table的数据源项使用Form.Listfields数据进行填充

show code

Container.tsx

import React from "react";
import { Button, Form, Table, Input, FormInstance } from "antd";
import { ColumnType } from "antd/es/table/interface";

type TypeProps = {
  form: FormInstance;
};
function formListTableColumns({
  form,
  remove
}: {
  form: FormInstance;
  remove: (index: number | number[]) => void;
}) {
  const columns = [
    {
      title: "a",
      dataIndex: "a",
      render: (text, record, index) => {
        return (
          <Form.Item name={[record.name, "a"]}>
            <Input />
          </Form.Item>
        );
      },
      width: 200
    },
    {
      title: "b",
      dataIndex: "b",
      width: 200,
      render: (text, record, index) => {
        return (
          <Form.Item name={[record.name, "b"]}>
            <Input />
          </Form.Item>
        );
      }
    },
    {
      title: "c",
      dataIndex: "c",
      width: 200,
      render: (text, record, index) => {
        return (
          <Form.Item name={[record.name, "c"]}>
            <Input />
          </Form.Item>
        );
      }
    },
    {
      title: "d",
      dataIndex: "d",
      width: 200,
      render: (text, record, index) => {
        return (
          <Form.Item name={[record.name, "d"]}>
            <Input />
          </Form.Item>
        );
      }
    },
    {
      title: "e",
      dataIndex: "e",
      width: 200,

      render: (text, record, index) => {
        return (
          <Form.Item name={[record.name, "e"]}>
            <Input />
          </Form.Item>
        );
      }
    },
    {
      title: "f",
      dataIndex: "f",
      width: 200,
      render: (text, record, index) => {
        return (
          <Form.Item name={[record.name, "f"]}>
            <Input />
          </Form.Item>
        );
      }
    },

    {
      title: "操作",
      dataIndex: "option",
      width: 100,
      fixed: "right",
      render: (text, record, index) => {
        return [
          <Form.Item name={[record.name, "q"]} hidden key="q"></Form.Item>,
          <Form.Item name={[record.name, "w"]} hidden key="w"></Form.Item>,
          <Form.Item name={[record.name, "e"]} hidden key="e"></Form.Item>,
          <Form.Item name={[record.name, "r"]} hidden key="r"></Form.Item>,
          <Form.Item name={[record.name, "t"]} hidden key="t"></Form.Item>,
          <Form.Item name={[record.name, "y"]} hidden key="y"></Form.Item>,
          <Button
            key="delete"
            onClick={() => {
              remove(record.name);
              const formData = form.getFieldsValue();
              /** 由于删除内容依旧会保留需要手动过滤,并重新赋值 */
              const newPriceList = (formData?.list || []).filter(
                (item: any) => {
                  if (!item.rowKey) {
                    return false;
                  }
                  return true;
                }
              );

              form.setFieldsValue({ list: newPriceList });
            }}
            style={{ color: "#ff4d4f" }}
          >
            删除
          </Button>
        ];
      }
    }
  ] as ColumnType<any>[];

  return columns;
}
export default function (props: TypeProps) {
  return (
    <Form.List name="list">
      {(fields, { add, remove }) => {
        return (
          <>
            <Table
              bordered
              scroll={{ x: 960 }}
              rowKey={"rowKey"}
              pagination={false}
              dataSource={fields}
              size="small"
              columns={formListTableColumns({ form: props.form, remove })}
            />
            <Form.Item>
              <Button
                style={{ width: "100%", marginBottom: 200 }}
                onClick={() => {
                  add({ rowKey: new Date().valueOf() });
                }}
                type="dashed"
              >
                + 增加
              </Button>
            </Form.Item>
          </>
        );
      }}
    </Form.List>
  );
}

代码解析

formListTableColumns

该方法接收form实现参数和Form.Listremove方法 在renderForm Itemname属性需要动态填入

<Form.Item name={[record.name, "f"]}>
    // 这里填充表单内容
</Form.Item>

record.name是表示当前行的form名称,f是当前字段

App.tsx

import React from "react";
import Container from "./Container";
import { Form } from "antd";

export default function (props: any) {
  const form = Form.useForm()[0];
  return (
    <div>
      <Form form={form}>
        <Container form={form} />
      </Form>
    </div>
  );
}

代码解析

这里直接使用组件,传入form实例,便于其它表单操作

Form.List 如何动态校验

这里可以使用dependencies来接收需要监听变化的字段 dependencies={[['list', record.name, 'f']]} list 是当前form list的表单字段名称 ,record.name是行表单的名称,f 是表示的是字段,注意这里需要使用数组嵌套的方式表示

具体实现 codesandbox