最近有一个需求,要手写可编辑表格,接下来我将针对各功能,各页面,进行详细的描述
* 查看态
*编辑态
*添加一行数据
一.思路
1.整体布局使用form包裹table,table的render,编辑状态下使用input,查看状态下使用text
renderType: edit ? 'input-name' : 'text-name',
*注:编辑状态下,渲染的删除列,是如何实现的?
1.单独写一个删除列对象
const action = ({ remove, add, len }) => {
return {
title: '操作',
fixed: 'right',
dataIndex: 'action',
key: 'action',
render: (_: any, record: any) => {
return (
<>
<Link
onClick={() => {
remove(record.name);
}}>
删除
</Link>
</>
);
},
};
};
2.判断,如果是编辑状态下,就使用concat() concat方法用于连接两个或多个数组()
<Form.Item>
<Table
pagination={false}
size={'small'}
title={() => props.title}
rowKey={'name'}
dataSource={fields}
columns={cls.concat(props.hideAction ? [] : action({ add, remove, len }))}
/>
</Form.Item>
2.添加、删除、确定实现方式
<Form.List name={props.formName || 'tableForm'}>
{(fields, { add, remove }) => {
const len = fields.length;
return (
<>
<div>
<Form.Item>
<Table
pagination={false}
size={'small'}
title={() => props.title}
rowKey={'name'}
dataSource={fields}
columns={cls.concat(props.hideAction ? [] : action({ add, remove, len }))}
/>
</Form.Item>
<Form.Item>
{edit && (
<div className="basic-information-add-button" onClick={() => add()}>
添加一行数据
</div>
)}
</Form.Item>
</div>
</>
);
}}
</Form.List>
1.添加 (建议大家看看ant-design的form里边的form.List)form.List自带add()、move()方法,使用就可以实现添加,删除!方便的很!!
*注:使用add和move方法,都要在form.List之下
我理解的form.List可以动态的为子组件实现添加(add),删除(move)方法,也可以进行校验
2.确定(确定就没什么可说的啦,根据自己的业务需求,form.getFieldsValue()拿到数据,然后写逻辑就可以了)
3.数据渲染
1.首先是查看态:就是table的表格渲染数据,没什么可说的
下面的Foem.Item是查看态,cls是继承来自父组件,下面展示父组件码
<div className="cip-capability-info-container" style={{ marginTop: 17 }}>
<Form form={form} name="basic">
<ListTableForm
hideAction={!edit}
edit={edit}
formName="packageProduct"
fields={basicData}
basicData={basicData}
cls={[
{
title: '参数名',
name: 'name',
dataIndex: 'name',
key: 'name',
renderType: edit ? 'input-name' : 'text-name',
},
{
title: '默认值',
name: 'value',
dataIndex: 'value',
key: 'value',
renderType: edit ? 'input-value' : 'text-value',
},
{
title: '描述',
name: 'description',
dataIndex: 'description',
key: 'description',
renderType: edit ? 'input-description' : 'text-description',
},
]}
/>
<Form.Item>
<Space>
{edit ? (
<>
<Button onClick={onFinish} type="primary" htmlType="submit">
确定
</Button>
<Button
onClick={() => {
setEdit(false);
}}>
取消
</Button>
</>
) : (
<Button
type="primary"
onClick={() => {
setEdit(true);
form.setFieldsValue({ packageProduct: basicData });
}}>
编辑
</Button>
)}
</Space>
</Form.Item>
</Form>
</div>
2.子组件数据渲染 *注:子组件的数据,在点击编辑的时候,使用form.setFieldsValue()放进表格里,
const ListTableForm: React.FC<PropsType> = (props: PropsType) => {
const { edit, basicData } = props;
const rules = [{ required: true, message: '请填充内容!' }];
const [cls, setCls] = useState<any[]>([]);
function renderType(_: any, record: any, index: any, other: any) {
const { renderType } = other; //renderType是让编辑态的表格,继承查看态的表格
switch (renderType) {
case 'input-name':
return (
<Form.Item
rules={rules}
name={[record.name, other.name]}
fieldKey={[record.fieldKey, other.name]}>
<Input defaultValue={record.name} />
</Form.Item>
);
case 'input-value':
return (
<Form.Item
rules={rules}
name={[record.name, other.name]}
fieldKey={[record.fieldKey, other.name]}>
<Input defaultValue={record.value} />
</Form.Item>
);
case 'input-description':
return (
<Form.Item
rules={rules}
name={[record.name, other.name]}
fieldKey={[record.fieldKey, other.name]}>
<Input defaultValue={record.description} />
</Form.Item>
);
case 'text-name':
return (
<Form.Item
rules={rules}
name={[record.name, other.name]}
fieldKey={[record.fieldKey, other.name]}>
<Text>{record.name}</Text>
</Form.Item>
);
case 'text-value':
return (
<Form.Item
rules={rules}
name={[record.name, other.name]}
fieldKey={[record.fieldKey, other.name]}>
<Text>{record.value}</Text>
</Form.Item>
);
case 'text-description':
return (
<Form.Item
rules={rules}
name={[record.name, other.name]}
fieldKey={[record.fieldKey, other.name]}>
<Text>{record.description}</Text>
</Form.Item>
);
default:
return (
<Form.Item shouldUpdate={true}>
{({ getFieldValue }) => {
return (getFieldValue(props.formName) || [])?.[index]?.[other?.name];
}}
</Form.Item>
);
}
}
useEffect(() => {
const _newProps = props.cls.map((item) => {
const { render, ...resetProps } = item;
return {
...resetProps,
render: (text: any, record: any, index: any) => renderType(text, record, index, item),
};
});
setCls(_newProps);
}, [props.cls]);
return (
<>
{edit ? (
<Form.List name={props.formName || 'tableForm'}>
{(fields, { add, remove }) => {
const len = fields.length;
return (
<>
<div>
<Form.Item>
<Table
pagination={false}
size={'small'}
title={() => props.title}
rowKey={'name'}
dataSource={fields}
columns={cls.concat(props.hideAction ? [] : action({ add, remove, len }))}
/>
</Form.Item>
<Form.Item>
{edit && (
<div className="basic-information-add-button" onClick={() => add()}>
添加一行数据
</div>
)}
</Form.Item>
</div>
</>
);
}}
</Form.List>
) : (
<Form.Item>
<Table pagination={false} dataSource={basicData} columns={cls} />
</Form.Item>
)}
</>
);
};
export default ListTableForm;
好啦 这样就能实现啦 如有疑问 欢迎指教!
问题:1.在新增一条数据的时候,用add()方法,会导致第一排数据出现name:index(index为0,1,2,3,4)
解决办法:add(name:'')