react Antd 表格+可编辑行配置

Antd 基础表格很容易设置,但是对于可编辑的行的配置,确实需要一点细心。对于刚入门,或者不太懂这个配置的来说无疑是奔溃的。今天就来记录下一个简单的可编辑行配置的步骤。
表格需要的基础数据

Table 组件  Column组件
一个模拟数据的Array   一个 column 设置的 Array
其中 key 值只是用来标识数据的 key
editable 是用来判断 当前某行某列单元格内容是否处于正在编辑状态
const [data, setDataSource] = useState([
        {
            key: '1',
            order: '1',
            keyName: '连衣裙',
        },
        {
            key: '2',
            order: '2',
            keyName: '裤子',
        }
    ])
const columns = [
        {
            title: 'order',
            editable: true,
            dataIndex: 'order'
        },
        {
            title: 'keyName',
            editable: true,
            dataIndex: 'keyName'
        },
]

上边是基础数据。接下来根据 columns 数组来生成 对应表格的每一列的配置
此处利用map来操作
其中inputType 是用来判断单元格内容应该是 输入框还是数值框,这部分在本次示例中没有用到,这里仅仅是提及一下。

\color{CadetBlue}{ 事实上官方文档API也没有谈及-列的属性 editing }
表格 Table - Ant Design,此处可点击自己查看
\color{CadetBlue}{其实他非常重要。}
\color{CadetBlue}{它用来表示当前单元格内容是否是编辑状态}
\color{CadetBlue}{而动态控制这个值的就是上面columns 数组提到的 editable 值)}
而isEditing 函数用来设置对应的 行数据 是否编辑状态,由 editingKey控制。那么 setEditingKey在哪里调用呢?
🍔🍗答: 每行数据最后加个 功能单元格 然后点击触发函数 即可(看下边!)

const [editingKey, setEditingKey] = useState(''); //初始化为空
const isEditing = (record) => record.key === editingKey;
    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), !!!!注意这里
            }),
        };
    });



(有人可能蒙圈了,怎么又是行编辑又是列的属性的编辑editing?
🍔🍗答: 每一行数据有一个 key值, 当与 editingKey 相等,代表当前行数据处于编辑状态。editingKey 由 setEditingKey控制,用户调用setEditingKey('key?') 来控制某行要编辑 。而单元格由 editing 来配置编辑状态,
故而 record.key === editingKey 如果为 true 则 那一行的所有单元格 的 editing 都为 true,则实现整行都处于编辑状态)

功能单元格:::

上边的 columns 数组改写。增加 title 为 operation 的单元格
通过 每行的 Typography.Link 按钮-edit 函数来调用 setEditingKey() 更改值。
{\color{red}{\text{部分代码细节不讲,自己能看懂}}}

import { Form, Table, Input, InputNumber, Popconfirm, Typography } from 'antd'
const cancel = () => {
        setEditingKey('');
      };
const handleDelete = (key) => {
        const newData = data.filter((item) => item.key !== key);
        setDataSource(newData);
    };
const edit = (record) => {
        form.setFieldsValue({ //此处初始化form 组件的值
            // key: '3',
            order: '',
            keyName: '',
            ...record,
        });
        setEditingKey(record.key); //此处更改 editingKey 值!!!
    };
const columns = [
        {
            title: 'order',
            editable: true,
            dataIndex: 'order'
        },
        {
            title: 'keyName',
            editable: true,
            dataIndex: 'keyName'
        },
       
        {
            title: 'operation',
            dataIndex: 'operation',
            render: (_, record) => {
                const editable = isEditing(record);
                return editable ? (
                    <>
                        <Popconfirm title="Sure to delete?" onConfirm={() => handleDelete(record.key)}>
                            <a>Delete</a>
                        </Popconfirm>
                        <Popconfirm title="Sure to cancel?" onConfirm={cancel}>
                            <a>Cancel</a>
                        </Popconfirm>
                    </>
                ) : <Typography.Link disabled={editingKey !== ''} onClick={() => edit(record)}>
                    Edit
                </Typography.Link>
            }
        }
    ]

上边都是 主要讲解其中的逻辑,接下来就是渲染UI table组件即可

设置form表单元素 样式组件
const EditableCell = ({
    editing,
    dataIndex,
    title,
    inputType,
    record,
    index,
    children,
    ...restProps
}) => {
    const inputNode = inputType === 'number' ? <InputNumber /> : <Input />;
    return (
        <td {...restProps}>
            {editing ? (
                <Form.Item
                    name={dataIndex}
                    style={{
                        margin: 0,
                    }}
                    rules={[
                        {
                            required: true,
                            message: `Please Input ${title}!`,
                        },
                    ]}
                >
                    {inputNode}
                </Form.Item>
            ) : (
                children
            )}
        </td>
    );
};

把form 模板加入到 Table 的 components中::::

{\color{red}{\text{值得注意的是,想在table中编辑内容,得加 入Form表单元素 ,把 table 组件包裹 }}}

const [form] = Form.useForm();

<Form form={form} component={false}>
      <Table
             components={{
               body: {
                 cell: EditableCell,
             },
         }}
         columns={mergedColumns}
        dataSource={data} 
      pagination={{ total: '50', showQuickJumper: true,    
      showSizeChanger: true, 
      pageSize: '5', size: "small" }}>
 </Table>
</Form>   

整个组件的完整代码如下:

import { Form, Table, Input, InputNumber, Popconfirm, Typography } from 'antd'
import { Button } from 'antd/lib/radio';
import React from 'react'
import { useState } from 'react';

const { Column, ColumnGroup } = Table

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

export default function LeftCard() {
    const [form] = Form.useForm();
    const [editingKey, setEditingKey] = useState('');
    const [data, setDataSource] = useState([
        {
            key: '1',
            order: '1',
            keyName: '连衣裙',
           
        },
        {
            key: '2',
            order: '2',
            keyName: '裤子',
          
        },

    ])
    const columns = [
        {
            title: 'order',
            editable: true,
            dataIndex: 'order'
        },
        {
            title: 'keyName',
            editable: true,
            dataIndex: 'keyName'
        },
        {
            title: 'operation',
            dataIndex: 'operation',
            render: (_, record) => {
                const editable = isEditing(record);
                return editable ? (
                    <>
                        <Popconfirm title="Sure to delete?" onConfirm={() => handleDelete(record.key)}>
                            <a>Delete</a>
                        </Popconfirm>
                        <Popconfirm title="Sure to cancel?" onConfirm={cancel}>
                            <a>Cancel</a>
                        </Popconfirm>
                    </>
                ) : <Typography.Link disabled={editingKey !== ''} onClick={() => edit(record)}>
                    Edit
                </Typography.Link>
            }
        }
    ]
    const cancel = () => {
        setEditingKey('');
      };
    const isEditing = (record) => record.key === editingKey;
    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),
            }),
        };
    });
    function pageChange(pagination, filters, sorter, extra) {
        console.log(extra)
    }

    const handleDelete = (key) => {
        const newData = data.filter((item) => item.key !== key);
        setDataSource(newData);
    };
    const edit = (record) => {
        form.setFieldsValue({
            // key: '3',
            order: '',
            keyName: '',
            ...record,
        });
        setEditingKey(record.key);
    };
    return (
        <>
            <Form form={form} component={false}>
                <Table
                    components={{
                        body: {
                            cell: EditableCell,
                        },
                    }}
                    columns={mergedColumns}
                    dataSource={data} 
                    onChange={pageChange} 
                    pagination={{ total: '50', showQuickJumper: true, showSizeChanger: true, pageSize: '5', size: "small" }}>
                  
                </Table>
            </Form>
        </>
    )
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容