--- order: 24 title: en-US: Editable Rows zh-CN: 可编辑行 --- ## zh-CN 带行编辑功能的表格。 > 🛎️ 想要 3 分钟实现?试试 [ProTable 的可编辑表格](https://procomponents.ant.design/components/editable-table)! ## en-US Table with editable rows. ```tsx import React, { useState } from 'react'; import { Table, Input, InputNumber, Popconfirm, Form, Typography } from 'antd'; interface Item { key: string; name: string; age: number; address: string; } const originData: Item[] = []; for (let i = 0; i < 100; i++) { originData.push({ key: i.toString(), name: `Edrward ${i}`, age: 32, address: `London Park no. ${i}`, }); } interface EditableCellProps extends React.HTMLAttributes { editing: boolean; dataIndex: string; title: any; inputType: 'number' | 'text'; record: Item; index: number; children: React.ReactNode; } const EditableCell: React.FC = ({ editing, dataIndex, title, inputType, record, index, children, ...restProps }) => { const inputNode = inputType === 'number' ? : ; return ( {editing ? ( {inputNode} ) : ( children )} ); }; const EditableTable = () => { const [form] = Form.useForm(); const [data, setData] = useState(originData); const [editingKey, setEditingKey] = useState(''); const isEditing = (record: Item) => record.key === editingKey; const edit = (record: Partial & { key: React.Key }) => { form.setFieldsValue({ name: '', age: '', address: '', ...record }); setEditingKey(record.key); }; const cancel = () => { setEditingKey(''); }; const save = async (key: React.Key) => { try { const row = (await form.validateFields()) as Item; 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: (_: any, record: Item) => { const editable = isEditing(record); return editable ? ( save(record.key)} style={{ marginRight: 8 }}> Save Cancel ) : ( edit(record)}> Edit ); }, }, ]; const mergedColumns = columns.map(col => { if (!col.editable) { return col; } return { ...col, onCell: (record: Item) => ({ record, inputType: col.dataIndex === 'age' ? 'number' : 'text', dataIndex: col.dataIndex, title: col.title, editing: isEditing(record), }), }; }); return (
); }; export default () => ; ``` ```css .editable-row .ant-form-item-explain { position: absolute; top: 100%; font-size: 12px; } ```