使用antd的可编辑表格

5,025 阅读1分钟
import React, { useState } from 'react';
import { Form, Input, Table, Button, Typography } from 'antd';
const [data, setData] = useState([]); //存放表格内容
const [form] = Form.useForm();
const [editingKey, setEditingKey] = useState('');

页面元素

<div className={styles.btn} style={{ width: '100px' }} onClick={add}>添加新行</div>
<div className={styles.tableWrapper}>
    <Form form={form} component={false}>
        <Table
            components={{
                body: {
                    cell: EditableCell,
                },
            }}
            bordered
            dataSource={data}
            columns={mergedColumns}
            rowClassName="editable-row"
            pagination={false}
        />
    </Form>
</div>

配置

const EditableCell = ({
    editing,
    dataIndex,
    title,
    inputType,
    record,
    index,
    children,
    ...restProps
}) => {
    const inputNode = <Input autoComplete="off" />;
    return (
        <td {...restProps}>
            {editing ? (
                <Form.Item
                    name={dataIndex}
                    style={{
                        margin: 0,
                    }}
                    rules={[
                        {
                            required: true,
                            message: `请输入${title}!`,
                        },
                    ]}
                >
                    {inputNode}
                </Form.Item>
            ) : (
                children
            )}
        </td>
    );
};

columns的内保存、取消、编辑操作

const edit = (record) => {
    form.setFieldsValue({
        personName: '',
        companyName: '',
        recommendedTime: '',
        ...record,
    });
    setEditingKey(record.key);
};

const cancel = () => {
    setEditingKey('');
};

const save = async (key) => {
    try {
        const row = await form.validateFields();
        const newData = [...data];
        const index = newData.findIndex((item) => key === item.key);

        if (index > -1) {
            const item = newData[index];
            newData.splice(index, 1, { ...item, ...row });
            setData(newData);
            setEditingKey('');
        } else {
            newData.push(row);
            setData(newData);
            setEditingKey('');
        }
    } catch (errInfo) {
        console.log('保存失败', errInfo);
    }
};

columns

const columns = [
    {
        title: '推荐的人才',
        dataIndex: 'personName',
        width: '25%',
        editable: true,
    },
    {
        title: '入驻的企业',
        dataIndex: 'companyName',
        width: '40%',
        editable: true,
    },
    {
        title: '推荐时间',
        dataIndex: 'recommendedTime',
        width: '15%',
        editable: true,
    },
    {
        title: '操作',
        dataIndex: 'operation',
        render: (_, record) => {
            const editable = isEditing(record);
            return editable ? (
                <span>
                    <a
                        onClick={() => save(record.key)}
                        style={{
                            marginRight: 8,
                        }}
                    >
                        保存
                    </a>
                    <a onClick={cancel}>取消</a>
                </span>
            ) : (
                <Typography.Link disabled={editingKey !== ''} onClick={() => edit(record)}>
                    编辑
                </Typography.Link>
            );
        },
    },
];

// 依据是否可编辑返回不同元素
const mergedColumns = columns.map((col) => { 
    if (!col.editable) {
        return col;
    }
    return {
        ...col,
        onCell: (record) => ({
            record,
            inputType: col.dataIndex === 'age' ? 'number' : 'text',
            dataIndex: col.dataIndex,
            title: col.title,
            editing: isEditing(record),
        }),
    };
});

button添加新行

const add = () => { 
    data.push({
        key: "" + data.length,
        personName: '',
        companyName: '',
        recommendedTime: '',
    })
    setData([...data])
}