React使用antd实现可编辑单元格

import React, {
    
     useContext, useState, useEffect, useRef } from 'react';
import {
    
     Input, Form, } from 'antd';
import RSTable from '@com/RSTable';
import 'antd/dist/antd.css';
import '../styles/rssearch.less';
// 
import '../styles/rsedittables.less'

/**
 * 只适用于 单个单元格修改
 * 必传字段 :
 *       columns:[],
 *       dataSource:[]
 * 必传方法
 *      saveFun  用于改变input输入值之后触发的回调函数
 */

const EditableContext = React.createContext(null);

const EditableRow = ({
     
      index, ...props }) => {
    
    
    const [form] = Form.useForm();
    return (
        <Form form={
    
    form} component={
    
    false}>
            <EditableContext.Provider value={
    
    form}>
                <tr {
    
    ...props} />
            </EditableContext.Provider>
        </Form>
    );
};

const EditableCell = ({
     
     
    title,
    editable,
    children,
    dataIndex,
    record,
    saveFun,
    ...restProps
}) => {
    
    
    const [editing, setEditing] = useState(false);
    const inputRef = useRef(null);
    const form = useContext(EditableContext);
    useEffect(() => {
    
    
        if (editing) {
    
    
            inputRef.current.focus();
        }
    }, [editing]);

    const toggleEdit = () => {
    
    
        setEditing(!editing);
        form.setFieldsValue({
    
    
            [dataIndex]: record[dataIndex],
        });
    };

    const save = async () => {
    
    
        try {
    
    
            const values = await form.validateFields();
            toggleEdit();
            // 返回当前行信息  包括更改后的信息
            saveFun({
    
     ...record, ...values })
        } catch (errInfo) {
    
    
            console.log('Save failed:', errInfo);
        }
    };

    let childNode = children;
	//判断是否可编辑
    if (editable) {
    
    
        childNode = editing ? (
            <Form.Item
                style={
    
    {
    
    
                    margin: 0,
                    lineHeight: "27px"
                }}
                name={
    
    dataIndex}
                rules={
    
    [
                    {
    
    
                        required: true,
                        message: `${
      
      title} is required.`,
                    },
                ]}
            >
                <Input ref={
    
    inputRef} style={
    
    {
    
     height: "22px", borderRadius: "4px" }} onPressEnter={
    
    save} onBlur={
    
    save} />
            </Form.Item>
        ) : (
                <div
                    className="editable-cell-value-wrap"
                    style={
    
    {
    
    
                        paddingRight: 24,
                    }}
                    onClick={
    
    toggleEdit}
                >
                    {
    
    children}
                </div>
            );
    }

    return <td {
    
    ...restProps}>{
    
    childNode}</td>;
};

class EditableTable extends React.Component {
    
    
    static defaultProps = {
    
    
        columns: [],
        dataSource: []
    }
    render() {
    
    
        const {
    
     dataSource,columns,saveFun, ...rest } = this.props;
        // 每一行 每一个单元格 
        const components = {
    
    
            body: {
    
    
                row: EditableRow,
                cell: EditableCell,
            },
        };
        const newColumns = columns.map((col) => {
    
    
            if (!col.editable) {
    
    
                return col;
            }
            return {
    
    
                ...col,
                onCell: (record) => ({
    
    
                    record,
                    editable: col.editable,
                    dataIndex: col.dataIndex,
                    title: col.title,
                    saveFun: saveFun
                }),
            };
        });
        return (
            <div>
                <RSTable
                    {
    
    ...rest}
                    components={
    
    components}
                    rowClassName={
    
    () => 'editable-row'}
                    dataSource={
    
    dataSource}
                    columns={
    
    newColumns}
                />
            </div>
        );
    }
}

export default EditableTable

使用:

<RSEditTable
     bordered={
    
    false}
     size={
    
    'default'}
     columns={
    
    columns} //表格的列
     dataSource={
    
    dataTable} //表格渲染的数据
     title={
    
    tableName} //表格的名字
     pagination={
    
    false}
     saveFun={
    
    this.saveFun}
/>

columns:

 columns: [
                {
    
    
                    title: () => '序号(可编辑)',
                    dataIndex: 'priority',
                    width: '10%',
                    key: 'priority',
                    editable: true,
                },
                {
    
    
                    title: () => 'xx',
                    dataIndex: 'generate',
                    key: 'generate'
                },
                {
    
    
                    title: () => 'xx',
                    dataIndex: 'ttl',
                    key: 'ttl'
                },
                {
    
    
                    title: () => 'xx',
                    dataIndex: 'type',
                    key: 'type'
                },
                {
    
    
                    title: () => 'xx',
                    dataIndex: 'value',
                    key: 'value'
                },
                ]

editable属性为true的时候表示当前单元格可编辑;saveFun为该单元格离开焦点或者回车之后出发的回调函数。

saveFun:

saveFun=(item)=>{
    
    
      // item为当前行 的所有属性
    }

参考antd官方可编辑单元格:https://ant.design/components/table-cn/#components-table-demo-edit-cell

其实上边98%的代码都是固定写法,ctrl C V 即可实现…

猜你喜欢

转载自blog.csdn.net/qq_43291759/article/details/122838756#comments_21715176