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

news2024/12/25 13:59:06

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));

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1000056.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

windows10下同时安装两个mysql服务的解决办法

windows10下同时安装两个mysql服务的解决办法 安装MySQL8.0.18版本 安装解压版MySQL8.0.25 &#xff08;1&#xff09; 下载解压包 &#xff08;2&#xff09;配置my.ini文件 [mysqld] port 3307 #mysql安装目录 basedir D:\HuanJing\Mysql\mysql-8.0.25-winx64 #mysql数据存…

WebDAV之π-Disk派盘 + FV管理器

FV管理器是一款清爽简洁的文件管理器。支持Android系统免root访问data和obb目录的工具。通过无线网络管理文件,局域网文件共享。支持jpg,png,gif,bmp,webp,tif,heif,dng,avif,ico,APNG等格式的图片,可能是支持最多图片格式的文件管理App了。 支持zip,rar,7z,iso…

学会制作企业纪念相册,记录企业成长瞬间

企业成长瞬间&#xff0c;美好记忆永存&#xff01; 今天来给大家分享一个超级实用的技能&#xff0c;如何制作企业纪念相册呢&#xff1f; 想要记录下企业成长历程中的每一个美好瞬间&#xff0c;把回忆永久保存下来吗&#xff1f;那就跟着我一起往下看吧&#xff01; 首先&…

分享20+个在线工具网站,60+常用工具

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 今天给大家分享20在线工…

记录一次Docker与Redis冲突

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 报错以及Bug ✨特色专栏&#xff1a; …

知网被处罚5000万,加强合规意识迫在眉睫

近日&#xff0c;国内知名学术搜索平台知网被处罚5000万的消息引起了广泛关注。此次处罚不仅是对知网在数据管理和用户隐私保护方面存在违规行为的警示&#xff0c;也是侧面反映了政府部门对企业合规力度监管的升级&#xff0c;更是提醒企业和个人加强合规意识的重要性。 合规…

mes系统开发和上位机软件开发哪个方向前景更好?

MES系统开发和上位机软件开发都是与工业自动化相关的领域&#xff0c;各自有不同的前景和发展方向。下面是对两者的简要介绍和前景评估&#xff1a;MES系统开发&#xff1a;MES系统&#xff08;制造执行系统&#xff09;是用于实现制造业生产管理和信息化的软件系统。它涵盖了生…

2023年中秋节和国庆节放假几天?用待办软件记录放假安排并提醒

进入公历9月&#xff0c;我们都期待着下个长假的到来。那么2023年中秋节和国庆节放假几天呢&#xff1f;因为今年的中秋节是公历的9月29日&#xff0c;所以今年的中秋节和国庆节是连在一起放假的。放假时间安排是9月29日至10月6日&#xff0c;一共放假8天。而10月7日和8日则是调…

Quartus Ⅱ中遇到的问题

记录Quartus中遇到的报错 一、Failed to launch MegaWizard Plug-In Manager 报错&#xff1a;Failed to launch MegaWizard Plug-In Manager. PLL IntelFPGA IP v18.1 could not be found in the specified librarypaths. 原因&#xff1a;编译后无法再打开IP核查看了&…

FreeRTOS 内存管理策略

目录 1. FreeRTOS 的核心功能 2. 为什么 FreeRTOS 要自己实现内存管理 3. FreeRTOS 的5种内存管理策略 3.1 Heap_1&#xff08;只建不删&#xff09; 3.2 Heap_2&#xff08;Heap1_Pro、提供删除&#xff0c;产生碎片&#xff09; 内存碎片是怎么出现的 3.3 Heap_3&…

Stream流操作

一、流的分类 1.1 流的方向&#xff1a;输入流和输出流 输入流&#xff1a; 输入到计算机内存&#xff0c;键盘键入&#xff0c;文件读取等 输出流&#xff1a; 从计算机内存输出&#xff0c;写入显示器&#xff0c;文件写入等 1.2 流的功能&#xff1a;节点流和过滤流 节点流…

前端excel写入信息并下载

// 需要npm install xlsx&#xff0c;安装xlsx依赖 const data {management: {zh-cn: 管理,en-us: ,}, };function dataToFormat(data) {let newdata [];for (let i in data) {newdata.push({序号: i,,内容: data[i][zh-cn],});}return newdata; }function exportToExcel(old…

京东全品类指数查询API接口

京东全品类指数查询API接口&#xff08;Jingdong full category index query API interface&#xff09;是在京东平台的数据支撑基础上开发出来的一种应用程序编程接口&#xff0c;是由京东手机数码指数接口、食品饮料指数接口、母婴保健指数接口、服装鞋包指数接口、办公设备指…

开发者的商业智慧:产品立项策划你知道多少?

文章目录 想法的萌芽&#x1f31f;初步评估产品可行性&#x1f34a;分析核心功能和特点以及竞争对手&#x1f4dd;大健康监测&#x1f4dd;时尚新科技产品&#x1f4dd;准确性&#x1f4dd;多功能&#x1f4dd;品牌口碑&#x1f4dd;数据分析与个性化建议&#x1f4dd;社交互动…

vue中预览xml并高亮显示

项目中有需要将接口返回的数据流显示出来&#xff0c;并高亮显示&#xff1b; 1.后端接口返回blob,类型为xml,如图 2.页面中使用pre code标签&#xff1a; <pre v-if"showXML"><code class"language-xml">{{xml}}</code></pre> …

电阻和电容

目录 1、常见的电阻器 2、电容 ​编辑 1、常见的电阻器 对于电阻需要了解三个参数&#xff08;查询电阻的数据手册&#xff09;&#xff1a; 1、封装&#xff1a;就是电阻的尺寸或者大小&#xff0c;看焊在你的pcb板上是否合适。 2、标称&#xff1a;电阻的电阻大小、精度、…

学习笔记-静态路由配置有来无回导致无法访问目标IP

配置拓扑图&#xff1a; 已经在R1、R2、R3相应端口配置了相应IP。 在R2上配置静态路由&#xff1a; [R2]ip route-static 10.0.3.0 24 10.0.23.3 [R2]ip route-static 10.0.13.0 24 10.0.23.3执行tracert 10.0.3.3&#xff0c;可以到达目标IP 执行tracert 10.0.13.3&#xff…

夯实网络安全基石,筑牢网络安全防线

没有网络安全就没有国家安全&#xff0c;这句话我们常常能在各种新闻里看见。安全是发展的前提&#xff0c;发展是安全的保障&#xff0c;共同推进安全和发展。Z强调&#xff1a;“要坚持依法治网、依法办网、依法上网。”今年的国家网络安全宣传周在9月11日至17日全国范围内开…

win11右键任务栏没有任务管理器怎么办

大多数情况下&#xff0c;我们可以直接右击任务栏选择任务管理器打开&#xff0c;但是有小伙伴反映win11中右击任务栏没有任务管理器&#xff0c;遇到这种问题该怎么解决呢&#xff0c;这里小编就给大家详细介绍一下win11右击 任务栏没有任务管理器的解决方法&#xff0c;有需要…

HuTool 使用教程

HuTool 官网 Hutool — &#x1f36c;A set of tools that keep Java sweet. 一、简介 准备环境 Hutool是一个小而全的Java工具类库&#xff0c;通过静态方法封装&#xff0c;降低相关API的学习成本&#xff0c;提高工作效率&#xff0c;使Java拥有函数式语言般的优雅&#xff…