項目使用的是ant-pro模板
有個可編輯表格的需求,效果圖如下
ant-pro提供了EditableProTable 組件,我使用的是這種
https://procomponents.ant.design/components/editable-table
不過這里展示的默認都是input輸入框,我這里是需要下拉框和上傳組件
下拉框可以直接用select組件,不過upload需要自己封裝一下
因為這個可編輯表格獲取數據是根據綁定的value值,改變數據是onChange事件.upload組件沒有value值,對應的是defaultFileList, 而onChange事件返回的是file.fileList.
我們可以對這兩個屬性重新封裝,改成需要的格式
可編輯表格代碼
EditZTTable.tsx
import React, { useState } from 'react'
import { Row, Col, Select, Button } from 'antd'
import type { ProColumns } from '@ant-design/pro-table'
import { EditableProTable } from '@ant-design/pro-table'
import ComUpload from '@/components/ComUpload'
const { Option } = Select
type DataSourceType = {
id: React.Key
title?: string
role?: string
state?: string
created_at?: string
[propName: string]: any
}
const EditZTTable: React.FC = () => {
// 表格數據
const defaultData: DataSourceType[] = [
{
id: 624748504,
title: '活動名稱一',
role: '這個活動真好玩',
state: 'open',
created_at: '2020-05-26T09:42:56Z',
// attachments: [
// {
// uid: '1',
// name: 'xxx.png',
// status: 'done',
// response: 'Server Error 500', // custom error message to show
// url: 'http://www.baidu.com/xxx.png',
// }
// ]
},
{
id: 624691229,
title: '活動名稱二',
role: '這個活動真好玩',
state: 'closed',
created_at: '2020-05-26T08:19:22Z',
attachments: [
{
uid: '1',
name: 'xxx.png',
status: 'done',
response: 'Server Error 500', // custom error message to show
url: 'http://www.baidu.com/xxx.png',
},
{
uid: '2',
name: 'yyy.png',
status: 'done',
url: 'http://www.baidu.com/yyy.png',
}
]
},
]
// 設置選中的表格key
const [editableKeys, setEditableRowKeys] = useState<React.Key[]>(() =>
defaultData.map((item) => item.id),
)
// 設置表格數據
const [dataSource, setDataSource] = useState<DataSourceType[]>(() => defaultData)
const fileColumns: ProColumns<DataSourceType>[] = [
{
title: '序號',
dataIndex: 'num',
width: 55,
editable: false,
render: (_, record, index) => (
<span>{index + 1}</span>
)
},
{
title: '附件類型',
dataIndex: 'businessType',
renderFormItem: () => {
return <Select showSearch>
<Option value="jack">Jack</Option>
<Option value="lucy">Lucy</Option>
</Select>
},
formItemProps: {
rules: [
{
required: true,
whitespace: true,
message: '此項是必填項',
},
],
},
},
{
title: '附件上傳',
width: '50%',
dataIndex: 'attachments',
renderFormItem: () => (<ComUpload />),
},
{
title: '操作',
valueType: 'option',
width: 60,
render: (text, record) => [
<a
key="delete"
onClick={() => {
setDataSource(dataSource.filter((item) => item.id !== record.id))
}}
>
刪除
</a>,
],
},
]
return (
<>
<Row>
<Col span={24}>
<EditableProTable<DataSourceType>
columns={columns}
rowKey="id"
value={dataSource}
recordCreatorProps={{
newRecordType: 'dataSource',
record: () => ({
id: Date.now(),
}),
}}
editable={{
type: 'multiple',
editableKeys,
actionRender: (row, config, defaultDoms) => {
return [defaultDoms.delete]
},
onValuesChange: (record, recordList) => {
setDataSource(recordList)
},
onChange: (editableKeyss, editableRows: DataSourceType[]) => {
setEditableRowKeys(editableKeyss)
setDataSource(editableRows)
},
}}
/>
</Col>
</Row>
<Row>
<Col span={24} style={{ textAlign: 'right' }}>
<Button style={{ margin: '15px 8px 0' }} onClick={ () => { }}>重置</Button>
<Button type="primary" onClick={onSave}>保存</Button>
</Col>
</Row>
</>
)
}
export default EditZTTable
upload組件封裝
ComUpload.tsx
import React from 'react' import { Button, Upload } from 'antd' import { UploadOutlined } from '@ant-design/icons' type comuploadProps = { value?: { key: string; label: string; }[] onChange?: () => void } const ComUpload: React.FC<comuploadProps> = (props: comuploadProps) => { const attachments = props.value const { onChange } = props const action = `${URL_PREFIX}/file/upload` const changeFile = ({ file, fileList }) => { if (file.status !== 'uploading') { // console.log(file, fileList) const arr: any[] = [] fileList.forEach((item: any) => { if (item.response) { arr.push({ name: item.name, id: item.response.data }) } else { arr.push(item) } }) onChange(arr) } } return ( <Upload action={action} onChange={changeFile} defaultFileList={attachments} > <Button icon={<UploadOutlined />} type="text" /> </Upload> ) } export default ComUpload
