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


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

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

    最终效果:

    1. class EditableCell extends React.Component {
    2. state = {
    3. editing: false
    4. };
    5. toggleEdit = () => {
    6. const editing = !this.state.editing
    7. this.setState({ editing }, () => {
    8. if (editing) {
    9. this.input.focus()
    10. }
    11. })
    12. };
    13. save = e => {
    14. const { record, handleSave } = this.props;
    15. this.toggleEdit();
    16. handleSave(record, e.target.value)
    17. }; // save主要处理两件事,一是切换editing状态,二是提交更新的数据
    18. render() {
    19. const { children } = this.props
    20. const { editing } = this.state;
    21. return editing ? (
    22. <Input defaultValue={children} ref={node=>(this.input=node)} onPressEnter={this.save} onBlur={this.save} />
    23. ) : (
    24. <span>{children}<Icon type="edit" theme='twoTone' style={{marginLeft: 10}} onClick={this.toggleEdit} />span>
    25. )
    26. }
    27. };

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

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

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

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

    1. import React from 'react';
    2. import {Input, Icon} from 'antd';
    3. class EditableCell extends React.Component {
    4. state = {
    5. editing: false,
    6. text: this.props.children
    7. };
    8. toggleEdit = () => {
    9. const editing = !this.state.editing
    10. this.setState({ editing }, () => {
    11. if (editing) {
    12. this.input.focus()
    13. }
    14. })
    15. };
    16. save = e => {
    17. const { record, handleSave } = this.props;
    18. this.setState({text: e.target.value});
    19. this.toggleEdit();
    20. handleSave(record, e.target.value)
    21. };
    22. render() {
    23. const { editing, text } = this.state;
    24. return editing ? (
    25. <Input defaultValue={text} ref={node=>(this.input=node)} onPressEnter={this.save} onBlur={this.save} />
    26. ) : (
    27. <span>{text}<Icon type="edit" theme='twoTone' style={{marginLeft: 10}} onClick={this.toggleEdit} />span>
    28. )
    29. }
    30. };
    31. export default EditableCell;

    引入的时候:

    import { EditableCell } from '../EditableCell'

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

    1. import React, { useEffect } from 'react';
    2. import { PageHeaderWrapper } from '@ant-design/pro-layout';
    3. import { Card, Input, Select, Row, message, Col, Table, Button, Icon, Upload, Form, DatePicker } from 'antd';
    4. import { connect } from 'dva';
    5. import download from '@/utils/download';
    6. import styles from './style.less';
    7. const { Option } = Select;
    8. class EditableCell extends React.Component {
    9. state = {
    10. editing: false
    11. };
    12. toggleEdit = () => {
    13. const editing = !this.state.editing
    14. this.setState({ editing }, () => {
    15. if (editing) {
    16. this.input.focus()
    17. }
    18. })
    19. };
    20. save = e => {
    21. const { record, handleSave } = this.props;
    22. this.toggleEdit();
    23. handleSave(record, e.target.value)
    24. };
    25. render() {
    26. const { children } = this.props
    27. const { editing } = this.state;
    28. return editing ? (
    29. <Input defaultValue={children} ref={node=>(this.input=node)} onPressEnter={this.save} onBlur={this.save} />
    30. ) : (
    31. <span>{children}<Icon type="edit" theme='twoTone' style={{marginLeft: 10}} onClick={this.toggleEdit} />span>
    32. )
    33. }
    34. };
    35. const Aabbb = props => {
    36. const { form, dispatch, dataLoading } = props;
    37. const { getFieldDecorator } = form;
    38. const { pageInfo, res } = props;
    39. const formItemLayout = {
    40. labelCol: { span: 8 },
    41. wrapperCol: { span: 16 },
    42. };
    43. const columns = [
    44. { title: '序号', dataIndex: 'id', align: 'center', width: 80, fixed: 'left', render: (text, record, index) =>
    45. (<span>{(pageInfo.current - 1) * pageInfo.pageSize + index + 1}span>)
    46. },
    47. ...
    48. { title: '结果', dataIndex: 'results', align: 'center', render: (text, record) => (
    49. <Select defaultValue={text} className={styles.tableSelection} onChange={value => handleModifyResult(value, record)}>
    50. <Option value="正常">正常Option>
    51. <Option value="异常">异常Option>
    52. Select>
    53. )},
    54. { title: '备注', dataIndex: 'notes', align: 'center', width: 120, render: (text, record) => {
    55. return (<EditableCell handleSave={handleModifyNote} record={record}>{text}EditableCell>)
    56. }}
    57. ];
    58. const handleModifyNote = (record, value) => {
    59. console.log('save', {...record, notes: value})
    60. dispatch({})
    61. };
    62. const handleModifyResult = (value, record) => {
    63. dispatch({})
    64. console.log({...record, inspectionResults: value});
    65. };
    66. useEffect(() => {
    67. }, []);
    68. const queryData = () => {}
    69. return (
    70. <PageHeaderWrapper>
    71. <Card>
    72. <Form horizontal="true">
    73. <Row>
    74. <Col span={8}>
    75. ...
    76. Col>
    77. Row>
    78. <Row>
    79. ...
    80. Row>
    81. Form>
    82. <Table
    83. columns={columns}
    84. loading={dataLoading}
    85. dataSource={res}
    86. rowKey={(record,index)=>index}
    87. pagination={}
    88. onChange={}
    89. />
    90. Card>
    91. PageHeaderWrapper>
    92. );
    93. }
    94. export default connect(({ aabbb, loading }) => ({
    95. res: aabbb.res,
    96. dataLoading: loading.effects['aabbb/QueryAabbb'],
    97. }))(Form.create()(Aabbb));

  • 相关阅读:
    去除照片中多余人物方法分享-这些方法快收藏起来
    【Linux进程间通信】二、pipe管道
    易基因|病毒抗性:全基因组DNA甲基化揭示草鱼年龄相关病毒易感性的表观遗传机制
    JAVA 抽象类和接口——万字理解
    风力发电机液压偏航控制系统设计
    Python调用oracle存储过程返回游标结果
    Java-递归算法简要概括总结
    北邮《计算机网络》网络层笔记
    FreeRTOS教程8 任务通知
    npm install 安装包时,常用的-S 、-D 、-g 有什么区别?
  • 原文地址:https://blog.csdn.net/six66667/article/details/132740976