antd可编辑表格和拖拽
时间: 2023-11-06 10:51:17 浏览: 50
Antd提供了Table组件,可以实现表格的展示和编辑功能。而要实现可编辑表格和拖拽功能,需要对Table组件进行一些扩展。
1. 可编辑表格
Antd的Table组件提供了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. 拖拽
Antd的Table组件默认不支持拖拽功能,但是可以通过一些插件来实现。
其中,react-beautiful-dnd是一个比较常用的拖拽插件,可以很方便地和Antd的Table组件结合使用。具体实现步骤如下:
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} />
```