React+antd实现可编辑单元格,非官网写法,不使用可编辑行和form验证

antd3以上的写法乍一看还挺复杂,自己写了个精简版

没用EditableRow+Cell的结构,也不使用Context、高阶组件等,不使用form验证

最终效果:

class EditableCell extends React.Component {
    state = {
        editing: false
    };
    toggleEdit = () => {
        const editing = !this.state.editing
        this.setState({ editing }, () => {
            if (editing) {
                this.input.focus()
            }
        })
    };
    save = e => {
        const { record, handleSave } = this.props;
        this.toggleEdit();
        handleSave(record, e.target.value)

    };  // save主要处理两件事,一是切换editing状态,二是提交更新的数据
    render() {
        const { children } = this.props
        const { editing } = this.state;
        return editing ? (
            <Input defaultValue={children} ref={node=>(this.input=node)} onPressEnter={this.save} onBlur={this.save} />
        ) : (
            <span>{children}<Icon type="edit" theme='twoTone' style={{marginLeft: 10}} onClick={this.toggleEdit} /></span>
            )
    }
};

最后使用的时候直接在column元素的render里面<EditableCell> </EditableCell>就好啦, props一定要传处理保存修改的方法

render: (text, record) => {
    return (<EditableCell handleSave={handleModifyNote} record={record}>{text}</EditableCell>) //记得传props
    }

现在这个可编辑单元格组件在鼠标失焦或者回车后,列数据会变回修改前的数据,在state里面加个text,把最后显示的 {children} 换成 {text} 就可以。

该组件也许很多页面都会使用,单独放在一个文件里再引入会优雅很多:

import React from 'react';
import {Input, Icon} from 'antd';

class EditableCell extends React.Component {
    state = {
        editing: false,
        text: this.props.children
    };
    toggleEdit = () => {
        const editing = !this.state.editing
        this.setState({ editing }, () => {
            if (editing) {
                this.input.focus()
            }
        })
    };
    save = e => {
        const { record, handleSave } = this.props;
        this.setState({text: e.target.value});
        this.toggleEdit();
        handleSave(record, e.target.value)

    };
    render() {
        const { editing, text } = this.state;
        return editing ? (
            <Input defaultValue={text} ref={node=>(this.input=node)} onPressEnter={this.save} onBlur={this.save} />
        ) : (
            <span>{text}<Icon type="edit" theme='twoTone' style={{marginLeft: 10}} onClick={this.toggleEdit} /></span>
            )
    }
};

export default EditableCell;

引入的时候:

import { EditableCell } from '../EditableCell'

全部页面index.jsx大概是这样的

import React, { useEffect } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { Card, Input, Select, Row, message, Col, Table, Button, Icon, Upload, Form, DatePicker } from 'antd';
import { connect } from 'dva';
import download from '@/utils/download';
import styles from './style.less';

const { Option } = Select;

class EditableCell extends React.Component {
    state = {
        editing: false
    };
    toggleEdit = () => {
        const editing = !this.state.editing
        this.setState({ editing }, () => {
            if (editing) {
                this.input.focus()
            }
        })
    };
    save = e => {
        const { record, handleSave } = this.props;
        this.toggleEdit();
        handleSave(record, e.target.value)

    };
    render() {
        const { children } = this.props
        const { editing } = this.state;
        return editing ? (
            <Input defaultValue={children} ref={node=>(this.input=node)} onPressEnter={this.save} onBlur={this.save} />
        ) : (
            <span>{children}<Icon type="edit" theme='twoTone' style={{marginLeft: 10}} onClick={this.toggleEdit} /></span>
            )
    }
};

const Aabbb = props => {
    const { form, dispatch, dataLoading } = props;
    const { getFieldDecorator } = form;
    const { pageInfo, res }  = props;
    const formItemLayout = {
        labelCol: { span: 8 },
        wrapperCol: { span: 16 },
    };
    const columns = [
        { title: '序号', dataIndex: 'id', align: 'center', width: 80, fixed: 'left', render: (text, record, index) =>
            (<span>{(pageInfo.current - 1) * pageInfo.pageSize + index + 1}</span>)
        },
        ...
        { title: '结果', dataIndex: 'results', align: 'center', render: (text, record) => (
            <Select defaultValue={text} className={styles.tableSelection} onChange={value => handleModifyResult(value, record)}>
                <Option value="正常">正常</Option>
                <Option value="异常">异常</Option>
            </Select>
        )},
        { title: '备注', dataIndex: 'notes', align: 'center', width: 120, render: (text, record) => {
            return (<EditableCell handleSave={handleModifyNote} record={record}>{text}</EditableCell>)
        }}
    ];
    const handleModifyNote = (record, value) => {
        console.log('save', {...record, notes: value})
        dispatch({})
    };
    const handleModifyResult = (value, record) => {
        dispatch({})
        console.log({...record, inspectionResults: value});
    };
    
    
    useEffect(() => {
        
    }, []);
    const queryData = () => {}
        
    return (
        <PageHeaderWrapper>
            <Card>
                <Form horizontal="true">
                    <Row>
                        <Col span={8}>
                            ...
                        </Col>   
                    </Row>
                    <Row>
                        ...
                    </Row>
                </Form>
                <Table
                    columns={columns}
                    loading={dataLoading}
                    dataSource={res}
                    rowKey={(record,index)=>index}
                    pagination={}
                    onChange={}
                    />
            </Card>
        </PageHeaderWrapper>
    );
}

export default connect(({ aabbb, loading }) => ({
    res: aabbb.res,
    dataLoading: loading.effects['aabbb/QueryAabbb'],
}))(Form.create()(Aabbb));

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React中,使用Ant Design的Table组件,在表格中添加操作列并结合Dropdown和Menu组件可以实现更丰富的交互效果。 首先,我们需要导入相关的组件和样式: ```jsx import { Table, Dropdown, Menu, Button } from 'antd'; import { DownOutlined } from '@ant-design/icons'; import 'antd/dist/antd.css'; ``` 然后,在表格的columns中定义操作列,并使用Dropdown和Menu组件来定制操作菜单: ```jsx const columns = [ ...其他列定义, { title: '操作', key: 'action', render: (text, record) => ( <Dropdown overlay={menu}> <Button> 操作 <DownOutlined /> </Button> </Dropdown> ), }, ]; const menu = ( <Menu> <Menu.Item key="1"> <a target="_blank" rel="noopener noreferrer" href="#"> 编辑 </a> </Menu.Item> <Menu.Item key="2"> <a target="_blank" rel="noopener noreferrer" href="#"> 删除 </a> </Menu.Item> </Menu> ); ``` 以上代码中,columns定义了表格的列,其中操作列使用render属性来渲染。在render方法中,我们使用Dropdown组件来包裹Button,并将Menu作为overlay传入。 menu定义了操作菜单的内容,其中使用Menu.Item来定义菜单项,通过设置key属性来区分不同的菜单项。菜单项可以是一段文本或者其他React元素,这里我们使用a标签来模拟菜单项的操作。 最后,在Table组件中将columns配置为表格的列: ```jsx <Table columns={columns} dataSource={data} /> ``` 以上是在React使用Ant Design的Table组件添加操作列并结合Dropdown和Menu的写法,通过这种方式,我们可以方便地在表格中定制各种操作的菜单。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值