- 实现效果如图所示

import React, { useState } from "react";
import { Table, Input, InputNumber } from 'antd'
import { MinusCircleOutlined, PlusCircleOutlined } from "@ant-design/icons";
import styles from './style.less'
interface TableFromListItem {
key: number;
buyPrice: string,
b2bPrice: string,
minNumber: string,
maxNumber: string,
unit: string,
}
interface PropsType {
list?: TableFromListItem[];
unit?: string;
callback?: (data: any) => void;
}
export interface ActionType {
handleAdd: (value: number) => void;
handleRemove: (value: number) => void;
handleChange: (value: string, _: string, index: number) => void;
len: number;
}
const columns = (actions: ActionType) => {
const {handleAdd, handleRemove, handleChange, len} = actions
return [
{
title: '采购量最小值',
dataIndex: 'minNumber',
key: 'minNumber',
render: (text: number, record: TableFromListItem, index: number) =>
<InputNumber defaultValue={text}
placeholder="min"
onChange={value => {
handleChange(value, 'minNumber', index);
}}/>,
},
{
title: '采购量最大值',
dataIndex: 'maxNumber',
key: 'maxNumber',
render: (text: number, record: TableFromListItem, index: number) =>
<InputNumber defaultValue={text}
placeholder="max"
onChange={(value) => {
handleChange(value, 'maxNumber', index);
}}/>,
},
{
title: '采购单位',
dataIndex: 'unit',
key: 'unit',
width: 66,
},
{
title: '采购单价',
dataIndex: 'buyPrice',
key: 'buyPrice',
render: (text: number, record: TableFromListItem, index: number) =>
<InputNumber defaultValue={text}
precision={2}
formatter={value => `¥ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
parser={value => value.replace(/\¥\s?|(,*)/g, '')}
onChange={(value) => {
handleChange(value, 'buyPrice', index);
}}/>
},
{
title: 'B2B拿货单价',
dataIndex: 'b2bPrice',
key: 'b2bPrice',
render: (text: number, record: TableFromListItem, index: number) =>
<InputNumber defaultValue={text}
precision={2}
formatter={value => `¥ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
parser={value => value.replace(/\¥\s?|(,*)/g, '')}
onChange={(value) => {
handleChange(value, 'b2bPrice', index);
}}/>,
},
{
title: '',
dataIndex: 'key',
key: 'key',
render: (_: null, record: TableFromListItem, index: number) => <>
{len - 1 === index ?
<PlusCircleOutlined className={styles.iconButton}
onClick={() => handleAdd(record.key || index)}/> : null}
{len - 1 !== index ?
<MinusCircleOutlined className={styles.iconButton}
onClick={() => handleRemove(record.key || index)}/> : null}
</>,
},
]
};
const ListTableEdit: React.FC<PropsType> = (props: PropsType) => {
const {list, callback, unit} = props;
const nullObj = {b2bPrice: '', minNumber: '', maxNumber: '', unit: unit || '盒', buyPrice: '',}
const initList = list && list.length > 0 ? list : [{key: 0, ...nullObj}]
const [tableList, setTableList] = useState<TableFromListItem[]>(initList);
const handleAdd = (key: number) => {
const newData = tableList.map(item => ({...item}));
newData.push({
key: key + 1,
...nullObj,
});
setTableList(newData)
}
const handleRemove = (key: number) => {
setTableList(tableList.filter(item => item.key !== key));
}
const handleChange = (value: string, name: string, index: string | number) => {
tableList[index][name] = value;
callback ? callback(tableList) : '';
};
return <>
<Table className={styles.listTableEdit} bordered
pagination={false} dataSource={tableList}
columns={columns({
handleAdd,
handleRemove,
handleChange,
len: tableList.length
})}
/>
</>;
};
export default ListTableEdit;
- 我这儿的例子都是数字输入框,如果是input输入框value = e.target.value
- 其他文件
css
.listTableEdit {
:global {
.ant-table-tbody > tr > td .ant-input-number {
width: 100%;
}
.ant-table-thead > tr > th, .ant-table-tbody > tr > td, .ant-table tfoot > tr > th, .ant-table tfoot > tr > td {
padding: 4px;
text-align: center;
}
.ant-table-thead > tr > th {
color: rgba(0, 0, 0, 0.65);
font-weight: normal;
}
}
.iconButton {
margin: 0 8px;
color: @primary-color;
font-size: 16px;
line-height: 32px;
}
}