react + antd 实现表格单行编辑

前言

主要是是通过 Table 中 body 的集成来实现的,废话不多说上代码

步骤一

在 columns 中加入部分指定字段

import React, { useMemo } from 'react';
import { Button } from 'antd';

const [selectInfo, setSelectInfo] = useState({});

const isEditing = (record) => record.id === selectInfo.id;

const columns = useMemo(() => {
    return [
        {
            title: '姓名',
            dataIndex: 'name',
            width: 150,
            // 用于确定需要编辑的字段
            editable: true,
            // 编辑时对应的 form 类型
            componentType: 'input',
            message: '请输入姓名'
        },
        {
            title: '年龄',
            dataIndex: 'age',
            width: 120
        },
        {
            title: '性别',
            dataIndex: 'sex',
            width: 100,
            editable: true,
            componentType: 'radio',
            message: '请选择性别',
            render: (text) => (text === '0' ? '男' :  '女')
        },
        {
            title: '操作',
            dataIndex: '',
            width: 100,
            fixed: 'right',
            render: (text, record) => {
                // 判断是否进入编辑状态
                const editable = isEditing(record);
                return editable ? (
                    <div>
                        <Button type="link" onClick={saveInfo}>保存</Button>
                        <Button type="link" onClick={() => setSelectInfo({})}>取消</Button>
                    </div>
                ) : (
                    <div>
                        <Button type="link" onClick={() => setSelectInfo(record)}>编辑</Button>
                        <Button type="link" onClick={delInfo}>删除</Button>
                    </div>
                )
            }
        }
    ]
}, [params.current, isEditing, selectInfo])

步骤二

重点是以下两个方法,缺一不可

import { Radio, Form,Input } from 'antd';

const mergedColumns = columns.map(col => {
    if(!col.editable) {
        return col;
    }
    return {
        ...col,
        onCell: (record) => ({
            record,
            type: col.componentType,
            message: col.message,
            dataIndex: col.dataIndex,
            editing: isEditing(record)
        })
    }
})

const { Item } = Form;
const EditableCell = ({ editing, dataIndex, message, type, record, index, children, ...resetProps}) => {
    const inputNode = type === 'radio' ? (
        <Radio.Group
            options={[
                { label: '男', value: '0'},
                { label: '女', value: '1'},
            ]}
        />
    ) : (<Input placeholder={message} />);
    return (
        <td {...resetProps}>
            {editing ? (
                 <Item
                     name={dataIndex}
                     style={{margin: 0}}
                     rules={[{ required: true, message: message}]}
                 >
                     { inputNode }
                 </Item>
             ) : ( children )}
        </td>
    )
};

步骤三

接下来就简单了,插入到 table 中即可,顺便在外层放一层 form 用于表单校验

import { Form, Table } from 'antd'

<Form ref={tableRef} component={false}>
    <Table
        className="user-table"
        rowKey="id"
        components={{
            body:{
                cell: EditableCell
            }
        }}
        dataSource={dataSource.list}
        columns={mergedColumns}
    />    
</Form>

大功告成,剩下就是样式的修修补补啦!

posted @ 2022-07-07 14:50  蹦跶的比丢  阅读(1469)  评论(0编辑  收藏  举报