ProComponents之EditableProTable-可编辑表格

ProComponents之EditableProTable-可编辑表格

​ 对于初次使用ProComponents组件库的同学来说,官方文档过于复杂,本教程是帮助大家利用ProComponents库中的可编辑表格完成一个简答可编辑树形结构表格
在这里插入图片描述

EditableProTable基础属性配置:
rowKey="id" // 表格中每一行数据的key,要行数据中存在的属性名
actionRef={actionRef} // 定义行为实例,可用于后序新增数据
headerTitle="可编辑表格" // 表格的表题
recordCreatorProps={false} // 表格自带的新增按钮,设置为false不显示
columns={columns} // 表格表头
request={getData}// 可用于发起网请求获取表格数据 试例如下
// const getData = async (params: ApiType.ReqApiData) => {
//   const res = await selectApiInfoByPage(params);
//   return {
//     data: res.data.records.map(item => ({ ...item, key: item.id })),// 要渲染的表格数据
//     total: res.data.total, // 表格的条数,要分页就一定要返回
//     success: true, // 表示数据是否请求成功,一般设置为true
//   }
// }
value={dataSource} // 表格的数据
onChange={setDataSource} // 表格数据发生变化时调用
// 以上是高级表格的通用配置,以下是可编辑表格的一些配置
editable={{
	form, // 设置表单实例,用于表单验证
	editableKeys, // 当前在编辑的行的key
	onSave: async (rowKey, data, row) => {
		// 点击保存时调用
		console.log(rowKey, data, row);
	},
	onChange: setEditableRowKeys, // 编辑行发生变化时调用的方法
	actionRender: (row, config, dom) => [dom.save, dom.cancel], // 编辑时自定义操作按钮
}}
表头columns 常见配置:
const columns: ProColumns<DataSourceType>[] = [
    {
      dataIndex: 'name', // 表格对应的数据字段名
      title: "参数名", // 表格表头名
      ellipsis: true, // 是否开启自动缩进
    },
    {
      dataIndex: 'type',
      title: "参数类型",
      ellipsis: true,
      valueType: "select", // 数据类型,编辑时显示对应表单,默认text显示input输入框,select显示下拉框
      valueEnum: { // 数据枚举
        "String": "String",
        "Int": "Int",
        "Float": "Float",
        "Array": "Array",
        "Object": "Object"
      },
      formItemProps: { // 表单项配置
        validateTrigger: "onChange", // 验证时机 onChange 改变时验证  onBlur 失去焦点时验证  onSubmit 提交时验证
        rules: [ // 表单验证
          {
            required: true, // 是否必填
            message: '此项为必填项', // 错误提示
          },
          {
              validator(rule, value, callback) {
              // 自定义验证
              if (value === "Int") {
                callback("Int 类型已停用,请选择其他类型"); // 返回错误信息
              }
              callback(); // 验证通过
            },
          }
        ],
      },
    },
]
actionRef新增行方法配置:
// 添加到最后一条
actionRef.current?.addEditRecord?.(
    {
    	id: (Math.random() * 1000000).toFixed(0), // 新增数据的key,必填且唯一
        name: '新的一行',
    }
);
// 添加到指定父级下
actionRef.current?.addEditRecord?.(
    {
    	id: (Math.random() * 1000000).toFixed(0),// 新增数据的key,必填且唯一
        name: '新的一行',
    },
    {
        parentKey: record.id, // 指定父级的key
        //position?: "top" | "bottom" | undefined; // 添加的位置顶部或者底部(同一层级)
    	//newRecordType?: "dataSource" | "cache" | undefined; // 添加的方式,即一开始保存的发生,,保存到dataSource已有数据中或者cache缓存中
    }
);
建议:

ProComponents的文档过于复杂,大家有时候看不懂,可以ctrl+鼠标左键点击代码,查看源码,看看可以传哪些参数,还有就是可以结合 Ant Design 的文档查看,应为ProComponents是基于Ant Design封装的,Ant Design中的很多属性ProComponents中也同样可以用到

试例代码:
import type { ActionType, ProColumns } from '@ant-design/pro-components';
import {
  EditableProTable,
  useRefFunction
} from '@ant-design/pro-components';
import { Button, Form, Space, message } from 'antd';
import React, { useRef, useState, forwardRef, useImperativeHandle } from 'react';
import { Typography } from 'antd';

const { Title } = Typography;
// 表格字段类型
type DataSourceType = {
  id: React.Key;
  name?: string | undefined;
  address?: string | undefined;
  type?: string | undefined;
  requried?: boolean | undefined;
  defaultValue?: string | undefined;
  desc?: string | undefined;
  children?: DataSourceType[] | undefined;
}
// 表格默认数据
const defaultData: DataSourceType[] = [
  {
    id: "0",
    name: '活动名称一',
    address: '活动区域一',
    type: 'Object',
    requried: true,
    defaultValue: 'string',
    desc: '这个活动真好玩',
    children: [
      {
        id: "2",
        name: '活动名称er',
        address: '活动区域一',
        type: 'String',
        requried: true,
        defaultValue: 'string',
        desc: '这个活动真好玩',
      },
    ]
  },
  {
    id: "1",
    name: '活动名称san',
    address: '活动区域一',
    type: 'Array',
    requried: true,
    defaultValue: 'string',
    desc: '这个活动真好玩',
  },
];

const loopDataSourceFilter = (
  data: readonly DataSourceType[],
  id: React.Key | undefined,
): DataSourceType[] => {
  return data
    .map((item) => {
      if (item.id !== id) {
        if (item.children) {
          const newChildren = loopDataSourceFilter(item.children, id);
          return {
            ...item,
            children: newChildren.length > 0 ? newChildren : undefined,
          };
        }
        return item;
      }
      return null;
    })
    .filter(Boolean) as DataSourceType[];
};


export default forwardRef((props: { tableTitle: string, columns: ProColumns<DataSourceType>[] }, ref: React.ForwardedRef<any>) => {
  const actionRef = useRef<ActionType>(); // 行为实例,可用于后序新增等数据
  const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]); // 当前编辑行
  const [dataSource, setDataSource] = useState<readonly DataSourceType[]>([]); // 表格数据
  const [form] = Form.useForm(); // 表单实例
  // 删除行方法 传入当前行数据
  const removeRow = useRefFunction((record: DataSourceType) => {
    // 树形结构删除某行数据 loopDataSourceFilter(原始数据,删除行id)
    setDataSource(loopDataSourceFilter(dataSource, record.id));
  });
  // 表格表头
  const columns: ProColumns<DataSourceType>[] = [
    {
      dataIndex: 'name', // 表格对应的数据字段名
      title: "参数名", // 表格表头名
      ellipsis: true, // 是否开启自动缩进
    },
    {
      dataIndex: 'type',
      title: "参数类型",
      ellipsis: true,
      valueType: "select", // 数据类型,编辑时显示对应表单,默认text显示input输入框,select显示下拉框
      valueEnum: { // 数据枚举
        "String": "String",
        "Int": "Int",
        "Float": "Float",
        "Array": "Array",
        "Object": "Object"
      },
      formItemProps: { // 表单项配置
        validateTrigger: "onChange", // 验证时机 onChange 改变时验证  onBlur 失去焦点时验证  onSubmit 提交时验证
        rules: [ // 表单验证
          {
            required: true, // 是否必填
            message: '此项为必填项', // 错误提示
          },
        ],
      },
    },
    {
      dataIndex: 'required',
      title: "是否必填",
      ellipsis: true,
      render: (text: any) => { // 自定义渲染内容
        return text ? "是" : "否"
      }
    },
    {
      dataIndex: "defaultValue",
      title: "默认值",
      ellipsis: true,
    },
    {
      dataIndex: "desc",
      title: "参数说明",
      ellipsis: true,
    },
    {
      title: '操作',
      valueType: 'option',
      width: 250, // 表格列宽度
      render: (text, record, _, action) => [
        <Button
          type="primary"
          key="editable"
          onClick={() => {
            action?.startEditable?.(record.id);
          }}
        >
          编辑
        </Button>,
        <Button
          type="primary"
          key="delete"
          onClick={() => {
            removeRow(record);
          }}
        >
          删除
        </Button>,
        (record.type === "Array" || record.type === "Object") && <Button type="primary" onClick={() => {
          actionRef.current?.addEditRecord?.(
            {
              id: (Math.random() * 1000000).toFixed(0),
              name: '新的一行',
            },
            {
              parentKey: record.id
            }
          );
        }}>添加下级</Button>,
      ],
    },
  ];
  const onSave = () => {
    if (editableKeys.length) {
      message.error('请先保存参数')
      return [false];
    }
    return [true, dataSource];
  }
  // 把保存数据方法暴露出去,给父级使用
  useImperativeHandle(ref, () => {
    return {
      onSave
    }
  })
  return (
    <>
      <EditableProTable<DataSourceType>
        rowKey="id"// 表格中每一行数据的key,要行数据中存在的属性名
        scroll={{
          x: 960,
        }}
        actionRef={actionRef} // 定义行为实例,可用于后序新增数据
        // 表格的表题
        headerTitle={<Space>
          <Title level={4}>{props.tableTitle}</Title>
          <Button
            type="primary"
            onClick={() => {
              actionRef.current?.addEditRecord?.(
                {
                  id: (Math.random() * 1000000).toFixed(0),
                  name: '新的一行',
                }
              );
            }}
          >
            新增参数
          </Button>
          <Button onClick={onSave}>保存</Button>
        </Space>}
        maxLength={5}
        // 表格自带的新增按钮,设置为false不显示
        recordCreatorProps={false}
        columns={columns}
        // 可用于发起网请求获取表格数据
        request={async () => ({
          data: defaultData,
          total: 3,
          success: true,
        })}
        value={dataSource} // 表格的数据
        onChange={setDataSource} // 表格数据发生变化时调用的方法
        // 以上是高级表格的通用配置,以下是可编辑表格的一些配置
        editable={{
          form, // 设置表单实例,用于表单验证
          editableKeys, // 当前在编辑的行的key
          onSave: async (rowKey, data, row) => {
            // 点击保存时调用
            console.log(rowKey, data, row);
          },
          onChange: setEditableRowKeys, // 编辑行发生变化时调用的方法
          actionRender: (row, config, dom) => [dom.save, dom.cancel], // 编辑时自定义操作按钮
        }}
      />
    </>
  );
});


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值