Antd Table 可编辑表格

12 篇文章 0 订阅

antd Table 官方文档提及了 可编辑单元格可编辑行,这里解决 可编辑表格 

主要思路是将 antd Table 可编辑行  antd Form.List 相结合,将Table视为 Form.List 中循环的 Form.Item

可编辑表格

上代码:有部分注释

import React from 'react'
import { Form, Input, Button, Table, Select } from 'antd'
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import './index.css'

const TableEditForm = () => {
  const [form] = Form.useForm()

  const onFinish = values => {
    console.log(values)
  }

  const getColumns = (add, remove) => {
    return [
      {
        title: 'key',
        dataIndex: 'key'
      },
      {
        title: 'a链接',
        dataIndex: 'alink',
        render(text, field, index) {
          // 注意:这里的 field 不是当前行数据,而是 Form.List field
          return <Form.Item
            shouldUpdate={true}
          >
            {({ getFieldValue }) => {
              // 获取当前行数据,然后渲染你要的数据
              const record = (getFieldValue('tableForm') || [])?.[index] || {}
              return <a
                target='_blank'
                href={`/view-personne/list/detail?staffId=${
                  record?.id || ''
                }`} rel='noreferrer'
              >
                {record?.name}
              </a>
            }}
          </Form.Item>
        }
      },
      {
        title: '姓名',
        dataIndex: 'name',
        render(text, field) {
          // 这里的写法是 Form.List 的方法 https://ant.design/components/form-cn/#components-form-demo-dynamic-form-items
          return <Form.Item
            rules={ [{ required: true, message: '请输入姓名' }] }
            name={ [field.name, 'name'] }
            fieldKey={ [field.fieldKey, 'name'] }
          >
            <Input placeholder='请输入姓名' allowClear />
          </Form.Item>
        }
      },
      {
        title: '手机号',
        dataIndex: 'tel',
        render(text, field) {
          return <Form.Item
            rules={ [{ required: true, message: '请输入手机号' }] }
            name={ [field.name, 'tel'] }
            fieldKey={ [field.fieldKey, 'tel'] }
          >
            <Input placeholder='请输入姓名' allowClear />
          </Form.Item>
        }
      },
      {
        title: '学历',
        dataIndex: 'education',
        render(text, field) {
          return <Form.Item
            rules={ [{ required: true, message: '请选择学历' }] }
            name={ [field.name, 'education'] }
            fieldKey={ [field.fieldKey, 'education'] }
          >
            <Select placeholder='请输入姓名' allowClear>
              <Select.Option value='1'>专科</Select.Option>
              <Select.Option value='2'>本科</Select.Option>
              <Select.Option value='3'>研究生</Select.Option>
            </Select>
          </Form.Item>
        }
      },
      {
        title: '操作',
        dataIndex: 'operate',
        className: 'operate',
        width: 120,
        render(text, field) {
          return (
            <>
              <PlusOutlined onClick={() => add()} />
              <MinusCircleOutlined style={{ marginLeft: 10 }} onClick={() => remove(field.name)} />
            </>
          )
        }
      }
    ]
  }

  return (
    <>
      <Form className='table-edit-form' form={form} onFinish={onFinish} initialValues={{
        // 初始化两行
        tableForm: [{}, {}]
      }} >
        <Form.List name='tableForm'>
          { (fields, { add, remove }) => {
            // 将Table视为 Form.List 中循环的 Form.Item
            return (
              <Table
                dataSource={ fields }
                columns={ getColumns(add, remove) }
                rowKey='key'
                pagination={false}
              />
            )
          }}
        </Form.List>
        <Form.Item>
          <Button htmlType='submit' type='primary'>
            Submit
          </Button>
        </Form.Item>
      </Form>
    </>
  )
}

export default TableEditForm

index.css: 

.table-edit-form .ant-table-content  .ant-table-cell .ant-form-item {
    margin-bottom: 0;
}

另外,不推荐这种全表格形式的编辑,比较难理解和维护。更推荐antd可编辑行或者可编辑单元格的方式。 

如果有用,点个赞吧 (*^▽^*)

  • 23
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 29
    评论
Antd提供了Table组件,可以实现表格的展示和编辑功能。而要实现可编辑表格和拖拽功能,需要对Table组件进一些扩展。 1. 可编辑表格 AntdTable组件提供了editable属性,开启该属性后,表格单元格就可以进编辑了。同时,还需要在columns中配置每一列是否可编辑,以及编辑时的类型和属性。 例如,下面的代码可以实现一个简单的可编辑表格: ```jsx import { Table, Input, InputNumber, Popconfirm, Form } from 'antd'; import React, { useState } from 'react'; const EditableCell = ({ editing, dataIndex, title, inputType, record, index, children, ...restProps }) => { const inputNode = inputType === 'number' ? <InputNumber /> : <Input />; return ( <td {...restProps}> {editing ? ( <Form.Item name={dataIndex} style={{ margin: 0, }} rules={[ { required: true, message: `Please Input ${title}!`, }, ]} > {inputNode} </Form.Item> ) : ( children )} </td> ); }; const EditableTable = () => { const [form] = Form.useForm(); const [data, setData] = useState([ { key: '1', name: 'Edward King 0', age: 32, address: 'London, Park Lane no. 0', }, { key: '2', name: 'Edward King 1', age: 32, address: 'London, Park Lane no. 1', }, ]); const [editingKey, setEditingKey] = useState(''); const isEditing = (record) => record.key === editingKey; const edit = (record) => { form.setFieldsValue({ name: '', age: '', address: '', ...record, }); setEditingKey(record.key); }; const cancel = () => { setEditingKey(''); }; const save = async (key) => { try { const row = await form.validateFields(); const newData = [...data]; const index = newData.findIndex((item) => key === item.key); if (index > -1) { const item = newData[index]; newData.splice(index, 1, { ...item, ...row }); setData(newData); setEditingKey(''); } else { newData.push(row); setData(newData); setEditingKey(''); } } catch (errInfo) { console.log('Validate Failed:', errInfo); } }; const columns = [ { title: 'Name', dataIndex: 'name', width: '25%', editable: true, }, { title: 'Age', dataIndex: 'age', width: '15%', editable: true, }, { title: 'Address', dataIndex: 'address', width: '40%', editable: true, }, { title: 'Operation', dataIndex: 'operation', render: (_, record) => { const editable = isEditing(record); return editable ? ( <span> <a href="javascript:;" onClick={() => save(record.key)} style={{ marginRight: 8, }} > Save </a> <Popconfirm title="Sure to cancel?" onConfirm={cancel}> <a>Cancel</a> </Popconfirm> </span> ) : ( <a disabled={editingKey !== ''} onClick={() => edit(record)}> Edit </a> ); }, }, ]; const mergedColumns = columns.map((col) => { if (!col.editable) { return col; } return { ...col, onCell: (record) => ({ record, inputType: col.dataIndex === 'age' ? 'number' : 'text', dataIndex: col.dataIndex, title: col.title, editing: isEditing(record), }), }; }); return ( <Form form={form} component={false}> <Table components={{ body: { cell: EditableCell, }, }} bordered dataSource={data} columns={mergedColumns} rowClassName="editable-row" pagination={{ onChange: cancel, }} /> </Form> ); }; export default EditableTable; ``` 2. 拖拽 AntdTable组件默认不支持拖拽功能,但是可以通过一些插件来实现。 其中,react-beautiful-dnd是一个比较常用的拖拽插件,可以很方便地和AntdTable组件结合使用。具体实现步骤如下: 1. 安装react-beautiful-dnd插件 ```bash npm install react-beautiful-dnd ``` 2. 将Table组件封装成DragDropContext组件 ```jsx import { Table } from 'antd'; import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'; const DragTable = ({ columns, dataSource, onDragEnd }) => { return ( <DragDropContext onDragEnd={onDragEnd}> <Droppable droppableId="droppable"> {(provided) => ( <Table {...provided.droppableProps} ref={provided.innerRef} columns={columns} dataSource={dataSource} pagination={false} rowClassName="drag-row" onRow={(record, index) => ({ index, moveRow: true, })} /> )} </Droppable> </DragDropContext> ); }; export default DragTable; ``` 3. 实现onDragEnd回调函数 ```jsx const onDragEnd = (result) => { if (!result.destination) { return; } const { source, destination } = result; // 根据拖拽后的顺序重新排序dataSource const newData = [...dataSource]; const [removed] = newData.splice(source.index, 1); newData.splice(destination.index, 0, removed); // 更新dataSource setData(newData); }; ``` 最后,在页面中引用DragTable组件即可实现拖拽功能。例如: ```jsx <DragTable columns={columns} dataSource={data} onDragEnd={onDragEnd} /> ```
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__畫戟__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值