美文网首页
react Antd 表格+可编辑行配置

react Antd 表格+可编辑行配置

作者: 南土酱 | 来源:发表于2022-08-18 10:45 被阅读0次

    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>
            </>
        )
    }
    

    相关文章

      网友评论

          本文标题:react Antd 表格+可编辑行配置

          本文链接:https://www.haomeiwen.com/subject/mpoygrtx.html