react antd table 自定义表头功能
Ⅰ- 壹 - 功能展示和使用需求
需求描述
基于antd table 实现
自定义 table 的表头 内容 排序 宽度和顺序等 , 可根据自己的需求自己扩展
github:https://github.com/whqgo/ReactAntdTableCustomHeader
功能展示
Ⅱ - 贰 - 封装思路
TaskareaTableColumns: 主要对 弹框内容的封装
app.tsx:使用的方式 和对表头数据的描述
json.ts: 数据文件 主要用于模拟的数据
设计思路
用对象数组描述表格 然后进行解析读取处理 , 这是最原始的数据,
const [taskareaTableColumnsData, setTaskareaTableColumnsData] = useState({isShow: false, //控制显示隐藏type: 'taskarea',fields: fixedFields, // 当前字段的 模型数据 , 目的是为了 对字段的控制, 业务需要, // 用于修改 和默认columns: [// {// serial: '', // // lable: '', //表头的名称 多个用 / 隔开// lableRename: '', //表头的 重命名名称 优先级高于lable // value: [], // 要读取数据的字段key要读取数据的字段key 和 lable 关系对应// expression:'',// 表达式,fields存在的才能做计算// width: '',//宽度// defaultSortOrder: '',// 数据 的 排序方式// style:'',//样式// visible:'',//可视// noRender:true,// 是否 重写 render//... 和 antd table columns 配置一样// }{key: 'workDispatchOrdersProcessN.paiGongDanHao',id: '1', //serial: '1',// lable: ['工序名称', '派工单号'], //表头的名称 多个用 / 隔开lableRename: '工序/单号', //表头的 重命名名称 优先级高于lable title: '工序/单号', //表头的最终 重命名名称 优先级高于lable value: ['workDispatchOrdersProcessN', 'paiGongDanHao'], // 要读取数据的字段key 和 lable 关系对应expression: '',// 表达式,fields存在的才能做计算width: '',//宽度visible: true,//可视defaultSortOrder: '',// 数据 的 排序方式 styleType: 'def',//样式风格 def 默认文本 number 数字样式style: {},//样式align: 'center',//表头居中},{key: 'yxfw',id: '22', // serial: '22', // // lable: ['物品名称'], //表头的名称 多个用 / 隔开lableRename: '规格', //表头的 重命名名称 优先级高于lable title: '规格',value: ['yxfw'], // 要读取数据的字段keyexpression: '',// 表达式,fields存在的才能做计算width: '',//宽度defaultSortOrder: '',// 数据 的 排序方式visible: true,//可视styleType: 'def',//样式风格 def 默认文本 number 数字样式style: { flex: 3 },//样式align: 'center',//表头居中},{title: '操作',key: 'action',serial: '000000',id: 'aaa111bbb222ccc333',noRender: true,// 是否 重写 renderalign: 'center',//表头居中visible: true,//可视width: '300px',render: (_: any, record: any) => {return <div className='operation-item-content-taskarea'><div style={{ 'justifyContent': 'space-evenly', flex: '1' }}><div className='operation-badge-taskarea1'><div style={{}}><Button type="primary" onClick={() => {console.log("操作====按钮触发", record);}} size={'large'}>按钮</Button></div></div></div></div>},},],severalRows: 3// 控制合并行数})
我们可以在 useEffect进行动态控制 这里我们对 tableColumns 中的数据进行了二次处理 目的是在 这里就能获取到我当前的表头原始的数据,去控制最终要显示的数据处理,例如他的表头 文字 title,我需要根据两个值去判最终的结果,render中是根据我需求去做的处理
useEffect(() => {if (!taskareaTableColumnsData?.columns) returnif (workDispatchOrdersData?.length) {setTableColumns(() => (taskareaTableColumnsData.columns.reduce((preData: any, curData: any) => {// 判断是否可视if (curData.visible) {return curData.noRender ? [...preData, curData] : [...preData, {...curData,title: (record: any) => {let titleStr = curData?.lableRename || (taskareaTableColumnsData.fields.filter((f: any) => curData.value.includes(f.c))).map((f1: any) => f1.n).join('/')return <div>{titleStr}</div>},width: curData.width ? !isNaN(curData.width) ? curData.width + 'px' : curData.width : '',render: (_: any, record: any, index: any) => {return (<div className='operation-item-content-taskarea'><div>{(() => {switch (curData.styleType) {case 'def':return curData?.value?.map((cITem: any, i: number) => {return <div key={i}> {record[cITem]}</div>})case 'number':let socketMessageWSDataFind = null// 获取字段 模型的属性 let filterModels = fixedFields.filter((f: any) => curData?.value.includes(f.c))// 判断是不是 自定义的模型 需要特殊处理let customDefinitionFind: any = filterModels.find((f: any) => f.sourceDataType == "customDefinition")return <div style={{ justifyContent: 'start' }}>{/* <div className='operation-badge-taskarea'>{`${item['dmvl'] || 0}/${item['jiHuaShengChanShuLiang']}`}</div> */}{/* 没有推送的时候 查询模型 实际生产数量/计划生产数量 */}<div className='operation-badge-taskarea'>{curData?.expression ? eval(curData.expression) : curData?.value?.reduce((preValData: any, curValData: any) => {// return preValData + (record[curValData] ? (record[curValData]) : '')return [...preValData, record[curValData] || 0]}, []).join('/')}{/* 审核中 样式样式处理 */}{customDefinitionFind && <div className={customDefinitionFind?.className}>{eval(customDefinitionFind?.expression) || ''}</div>}</div></div>default:return curData?.value?.map((cITem: any, i: number) => {return <div key={i}> {record[cITem]}</div>})}})()}</div></div>)},onCell: (record: any, index: number) => {const cIndex = taskareaTableColumnsData.columns.findIndex(cItem => cItem.id === curData.id)if (curData.styleType === 'def' && cIndex + 1 <= taskareaTableColumnsData.severalRows) {try {if (index) { // 不是第一条const preD = workDispatchOrdersData[index - 1], nextD = workDispatchOrdersData[index];if (!preD || !nextD) return {}let preV = '', nextV = '';curData.value.map((item: string) => {preV += preD[item]nextV += nextD[item]})if (preV === nextV) { // 上一条和当前条相等,不渲染return { rowSpan: 0 }}}if (index !== workDispatchOrdersData.length - 1) { // 不是最后一条let unlikeIndex = workDispatchOrdersData.length - index; // 默认全部相等for (let i = index; i < workDispatchOrdersData.length; i++) {const nextD = workDispatchOrdersData[i + 1], currentD = workDispatchOrdersData[i];if (!nextD) break;let currentV = '', nextV = '';curData.value.map((item: string) => {currentV += currentD[item]nextV += nextD[item]})if (i !== workDispatchOrdersData.length - 1 && nextV !== currentV) { // 当前条和下一条不相等,就是需要合并的数unlikeIndex = i - index + 1break;}}return { rowSpan: unlikeIndex }}} catch (err) { console.log(err); }}return {}}}]} else {return preData}}, [])))}}, [workDispatchOrdersData, taskareaTableColumnsData.columns])
在弹框中 TaskareaTableColumns这个组件,就是把taskareaTableColumnsData.columns 中的配置当成数据去处理的,然后对他的内容做了自定义处理,详情看代码
github:https://github.com/whqgo/ReactAntdTableCustomHeader
Ⅲ - 叁 - 主要代码
APP.tsx使用
import { useEffect, useState } from 'react'
import './App.css'
import { Button, Checkbox, Input, InputNumber, Modal, Select, Space, Table } from 'antd';
import TaskareaTableColumns from './TaskareaTableColumns';
import { cloneDeep } from 'lodash'
import { fixedFields, MNData } from './json'
function App() {const [taskareaTableColumnsData, setTaskareaTableColumnsData] = useState({isShow: false, //控制显示隐藏type: 'taskarea',fields: fixedFields, // 当前字段的 模型数据 , 目的是为了 对字段的控制, 业务需要, // 用于修改 和默认columns: [// {// serial: '', // // lable: '', //表头的名称 多个用 / 隔开// lableRename: '', //表头的 重命名名称 优先级高于lable // value: [], // 要读取数据的字段key要读取数据的字段key 和 lable 关系对应// expression:'',// 表达式,fields存在的才能做计算// width: '',//宽度// defaultSortOrder: '',// 数据 的 排序方式// style:'',//样式// visible:'',//可视// noRender:true,// 是否 重写 render//... 和 antd table columns 配置一样// }{key: 'workDispatchOrdersProcessN.paiGongDanHao',id: '1', //serial: '1',// lable: ['工序名称', '派工单号'], //表头的名称 多个用 / 隔开lableRename: '工序/单号', //表头的 重命名名称 优先级高于lable title: '工序/单号', //表头的最终 重命名名称 优先级高于lable value: ['workDispatchOrdersProcessN', 'paiGongDanHao'], // 要读取数据的字段key 和 lable 关系对应expression: '',// 表达式,fields存在的才能做计算width: '',//宽度visible: true,//可视defaultSortOrder: '',// 数据 的 排序方式 styleType: 'def',//样式风格 def 默认文本 number 数字样式style: {},//样式align: 'center',//表头居中},{key: 'workDispatchOrdersItemN',id: '2', // serial: '2', // // lable: ['物品名称'], //表头的名称 多个用 / 隔开lableRename: '物品', //表头的 重命名名称 优先级高于lable title: '物品',value: ['workDispatchOrdersItemN'], // 要读取数据的字段keyexpression: '',// 表达式,fields存在的才能做计算width: '',//宽度defaultSortOrder: '',// 数据 的 排序方式visible: true,//可视styleType: 'def',//样式风格 def 默认文本 number 数字样式style: { flex: 3 },//样式align: 'center',//表头居中},{key: 'yxfw',id: '22', // serial: '22', // // lable: ['物品名称'], //表头的名称 多个用 / 隔开lableRename: '规格', //表头的 重命名名称 优先级高于lable title: '规格',value: ['yxfw'], // 要读取数据的字段keyexpression: '',// 表达式,fields存在的才能做计算width: '',//宽度defaultSortOrder: '',// 数据 的 排序方式visible: true,//可视styleType: 'def',//样式风格 def 默认文本 number 数字样式style: { flex: 3 },//样式align: 'center',//表头居中},{key: 'oiwo',id: '222', // serial: '222', // // lable: ['物品名称'], //表头的名称 多个用 / 隔开lableRename: '库存代码', //表头的 重命名名称 优先级高于lable title: '库存代码',value: ['oiwo'], // 要读取数据的字段keyexpression: '',// 表达式,fields存在的才能做计算width: '',//宽度defaultSortOrder: '',// 数据 的 排序方式visible: true,//可视styleType: 'def',//样式风格 def 默认文本 number 数字样式style: { flex: 3 },//样式align: 'center',//表头居中},{key: 'cqsw',id: '2222', // serial: '2222', // // lable: ['物品名称'], //表头的名称 多个用 / 隔开lableRename: '客户简称', //表头的 重命名名称 优先级高于lable title: '客户简称',value: ['cqsw'], // 要读取数据的字段keyexpression: '',// 表达式,fields存在的才能做计算width: '',//宽度defaultSortOrder: '',// 数据 的 排序方式visible: true,//可视styleType: 'def',//样式风格 def 默认文本 number 数字样式style: { flex: 3 },//样式align: 'center',//表头居中},{key: 'frbz.sene',id: '3',serial: '3',// lable: ['主设备名称'], //表头的名称 多个用 / 隔开lableRename: '主设备/设备部位', //表头的 重命名名称 优先级高于lable title: '主设备',value: ['frbz', 'sene'], // 要读取数据的字段keyexpression: '',// 表达式,fields存在的才能做计算width: '',//宽度defaultSortOrder: '',// 数据 的 排序方式visible: true,//可视styleType: 'def',//样式风格 def 默认文本 number 数字样式style: {},//样式align: 'center',//表头居中},{key: 'dmvl.jiHuaShengChanShuLiang.mvit',id: '4',serial: '4',lable: ['实际生产数量', '计划生产数量', '审核中'], //表头的名称 多个用 / 隔开lableRename: '实际生产数量/计划生产数量', //表头的 重命名名称 优先级高于lable title: '实际生产数量/计划生产数量',value: ['dmvl', 'jiHuaShengChanShuLiang', 'mvit'], // 要读取数据的字段keyexpression: "`${socketMessageWSDataFind ? (socketMessageWSDataFind['dmvl'] || record['dmvl'] || 0) : record['dmvl'] || 0}/${record['jiHuaShengChanShuLiang'] || 0}`",// 表达式,fields存在的才能做计算width: '',//宽度defaultSortOrder: '',// 数据 的 排序方式visible: true,//可视styleType: 'number',//样式风格 def 默认文本 number 数字样式style: { textAlign: 'start', flex: 3 },//样式\align: 'center',//表头居中},// {// key: 'dmvl.jiHuaShengChanShuLiang',// id: '5',// serial: '5',// lable: ['实际生产数量', '计划生产数量'], //表头的名称 多个用 / 隔开// lableRename: '实际生产数量12/计划生产数量333', //表头的 重命名名称 优先级高于lable // value: ['dmvl', 'jiHuaShengChanShuLiang'], // 要读取数据的字段key// expression: "",// 表达式,fields存在的才能做计算// width: '',//宽度// defaultSortOrder: '',// 数据 的 排序方式// visible: true,//可视// styleType: 'number',//样式风格 def 默认文本 number 数字样式// style: { textAlign: 'start', flex: 3 },//样式\// align: 'center',//表头居中// },{title: '操作',key: 'action',serial: '000000',id: 'aaa111bbb222ccc333',noRender: true,// 是否 重写 renderalign: 'center',//表头居中visible: true,//可视width: '300px',render: (_: any, record: any) => {return <div className='operation-item-content-taskarea'><div style={{ 'justifyContent': 'space-evenly', flex: '1' }}><div className='operation-badge-taskarea1'><div style={{}}><Button type="primary" onClick={() => {console.log("操作====按钮触发", record);}} size={'large'}>按钮</Button></div></div></div></div>},},],severalRows: 3// 控制合并行数})// 最终的 columnsconst [tableColumns, setTableColumns] = useState<any>([])const taskareaTableColumnsFillData = (FillDatType: any, tableColumnsFillData: any) => {// console.log(tableColumnsFillData, "===tableColumnsFillData===");// console.log(FillDatType, "===isShow===");// console.log(taskareaTableColumnsData, "===isShow===");if (FillDatType) {setTaskareaTableColumnsData((taskareaTableColumnsData: any) => {let _taskareaTableColumnsData = cloneDeep(taskareaTableColumnsData)_taskareaTableColumnsData.isShow = false_taskareaTableColumnsData.columns = [...tableColumnsFillData.tableData, _taskareaTableColumnsData.columns[_taskareaTableColumnsData.columns?.length - 1]]_taskareaTableColumnsData.severalRows = tableColumnsFillData.severalRowsreturn _taskareaTableColumnsData})} else {setTaskareaTableColumnsData((taskareaTableColumnsData: any) => ({ ...taskareaTableColumnsData, isShow: false }))}}const [workDispatchOrdersData, setWorkDispatchOrdersData] = useState<any>([])//数据// 初始化数据const getInit = async () => {setWorkDispatchOrdersData(() => MNData)}useEffect(() => {if (!taskareaTableColumnsData?.columns) return// console.log(taskareaTableColumnsData.columns, "====taskareaTableColumnsData.columns===");// console.log(workDispatchOrdersData, "====taskareaTableColumnsData.columns===");if (workDispatchOrdersData?.length) {setTableColumns(() => (taskareaTableColumnsData.columns.reduce((preData: any, curData: any) => {// 判断是否可视if (curData.visible) {return curData.noRender ? [...preData, curData] : [...preData, {...curData,title: (record: any) => {let titleStr = curData?.lableRename || (taskareaTableColumnsData.fields.filter((f: any) => curData.value.includes(f.c))).map((f1: any) => f1.n).join('/')return <div>{titleStr}</div>},width: curData.width ? !isNaN(curData.width) ? curData.width + 'px' : curData.width : '',render: (_: any, record: any, index: any) => {// console.log(_, record, index);// console.log(curData)return (<div className='operation-item-content-taskarea'><div>{(() => {switch (curData.styleType) {case 'def':return curData?.value?.map((cITem: any, i: number) => {return <div key={i}> {record[cITem]}</div>})case 'number':let socketMessageWSDataFind = null// 获取字段 模型的属性 let filterModels = fixedFields.filter((f: any) => curData?.value.includes(f.c))// 判断是不是 自定义的模型 需要特殊处理let customDefinitionFind: any = filterModels.find((f: any) => f.sourceDataType == "customDefinition")return <div style={{ justifyContent: 'start' }}>{/* <div className='operation-badge-taskarea'>{`${item['dmvl'] || 0}/${item['jiHuaShengChanShuLiang']}`}</div> */}{/* 没有推送的时候 查询模型 实际生产数量/计划生产数量 */}<div className='operation-badge-taskarea'>{curData?.expression ? eval(curData.expression) : curData?.value?.reduce((preValData: any, curValData: any) => {// return preValData + (record[curValData] ? (record[curValData]) : '')return [...preValData, record[curValData] || 0]}, []).join('/')}{/* 审核中 样式样式处理 */}{customDefinitionFind && <div className={customDefinitionFind?.className}>{eval(customDefinitionFind?.expression) || ''}</div>}</div></div>default:return curData?.value?.map((cITem: any, i: number) => {return <div key={i}> {record[cITem]}</div>})}})()}</div></div>)},onCell: (record: any, index: number) => {const cIndex = taskareaTableColumnsData.columns.findIndex(cItem => cItem.id === curData.id)if (curData.styleType === 'def' && cIndex + 1 <= taskareaTableColumnsData.severalRows) {try {if (index) { // 不是第一条const preD = workDispatchOrdersData[index - 1], nextD = workDispatchOrdersData[index];if (!preD || !nextD) return {}let preV = '', nextV = '';curData.value.map((item: string) => {preV += preD[item]nextV += nextD[item]})if (preV === nextV) { // 上一条和当前条相等,不渲染return { rowSpan: 0 }}}if (index !== workDispatchOrdersData.length - 1) { // 不是最后一条let unlikeIndex = workDispatchOrdersData.length - index; // 默认全部相等for (let i = index; i < workDispatchOrdersData.length; i++) {const nextD = workDispatchOrdersData[i + 1], currentD = workDispatchOrdersData[i];if (!nextD) break;let currentV = '', nextV = '';curData.value.map((item: string) => {currentV += currentD[item]nextV += nextD[item]})if (i !== workDispatchOrdersData.length - 1 && nextV !== currentV) { // 当前条和下一条不相等,就是需要合并的数unlikeIndex = i - index + 1break;}}return { rowSpan: unlikeIndex }}} catch (err) { console.log(err); }}return {}}}]} else {return preData}}, [])))}}, [workDispatchOrdersData, taskareaTableColumnsData.columns])useEffect(() => {getInit()}, [])return (<div className="App">{taskareaTableColumnsData.isShow && <TaskareaTableColumns data={taskareaTableColumnsData} fillData={taskareaTableColumnsFillData} />}<div><Button onClick={() => {setTaskareaTableColumnsData((data) => ({ ...data, isShow: true }))}}> 设置表头</Button></div>{tableColumns && <Tableborderedcolumns={tableColumns as any}className='taskarea-table-css'dataSource={workDispatchOrdersData}pagination={false}rowKey='id'/>}</div>)
}export default App
TaskareaTableColumns 封装
import React, { useState, useEffect, Fragment, useRef, useCallback } from 'react';
import './index.css';
import { Button, Checkbox, Input, InputNumber, Modal, Select, Space, Table } from 'antd';import update from 'immutability-helper';
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';import { cloneDeep } from 'lodash';interface DraggableBodyRowProps extends React.HTMLAttributes<HTMLTableRowElement> {index: number;moveRow: (dragIndex: number, hoverIndex: number) => void;
}const DraggableBodyRowType = 'DraggableBodyRow';const DraggableBodyRow = ({index,moveRow,className,style,...restProps
}: DraggableBodyRowProps) => {const ref = useRef<HTMLTableRowElement>(null);const [{ isOver, dropClassName }, drop] = useDrop({accept: DraggableBodyRowType,collect: monitor => {const { index: dragIndex } = monitor.getItem() || {};if (dragIndex === index) {return {};}return {isOver: monitor.isOver(),dropClassName: dragIndex < index ? ' drop-over-downward' : ' drop-over-upward',};},drop: (item: { index: number }) => {moveRow(item.index, index);},});const [, drag] = useDrag({type: DraggableBodyRowType,item: { index },collect: monitor => ({isDragging: monitor.isDragging(),}),});drop(drag(ref));return (<trref={ref}className={`${className}${isOver ? dropClassName : ''}`}style={{ cursor: 'move', ...style }}{...restProps}/>);
};const index: any = (props: any) => {const { fillData, type, model, data } = props;const [state, setState] = useState<any>({modalWidth: '60%',modalHeight: '55vh',});const [dataSource, setDataSource] = useState<any[]>([]);const [severalRows, setSeveralRows] = useState<any>()useEffect(() => {console.log(data.severalRows);setSeveralRows(data.severalRows)}, [data.severalRows])// 新增一条const addTableRow = () => {setDataSource((dataSource: any) => {let _dataSource = cloneDeep(dataSource)_dataSource.push({id: Date.now(),serial: _dataSource.length + 1,lable: null,visible: true,align: 'center',//表头居中})return _dataSource})}// 最终的 columnsconst [tableColumns, setTableColumns] = useState<any>([{title: '序号',key: 'index',dataIndex: 'index',width: '60px',render: (_: any, __: any, index: number) => index + 1, // 使用 index + 1 作为序号值},{title: '字段名称',dataIndex: 'value',key: 'value',noRender: true,styleType: 'multipleSelect',},{title: '显示名称',dataIndex: 'lableRename',key: 'lableRename',noRender: true,styleType: 'input',},{title: '可视',dataIndex: 'visible',key: 'visible',styleType: 'checkbox',noRender: true,},{title: '宽度',dataIndex: 'width',key: 'width',styleType: 'input',noRender: true,},// {// title: '排序',// dataIndex: 'defaultSortOrder',// key: 'defaultSortOrder',// styleType: 'select',// noRender: true,// },{title: '操作',key: 'option',width: 100,render: (_: any, record: any) => (<Space><Button type="primary" onClick={() => {// 删除setDataSource((dataSource: any) => {let _dataSource = cloneDeep(dataSource)let recindex = _dataSource.findIndex((f: any) => f.id == record.id)_dataSource.splice(recindex, 1)return _dataSource})}} danger>删除</Button></Space>),},])const moveRow = useCallback((dragIndex: number, hoverIndex: number) => {const dragRow = dataSource[dragIndex];setDataSource(update(dataSource, {$splice: [[dragIndex, 1],[hoverIndex, 0, dragRow],],}),);},[dataSource],);const onOK = async (type: any) => {if (type) {// console.log('%c [ 工作台设置提交 tableColumns] 日志', 'font-size:13px; background:#26A08F; color:#fff;', tableColumns);// console.log('%c [ 工作台设置提交 dataSource] 日志', 'font-size:13px; background:#26A08F; color:#fff;', dataSource);if (fillData) fillData(1, { tableData: cloneDeep(dataSource), severalRows })} else {if (fillData) fillData(0)}}const h = () => {if (!data) returnswitch (data.type) {case "taskarea":return (<><div>前<InputNumber style={{ margin: '0 5px 10px' }} min={1} value={severalRows} onChange={(val) => setSeveralRows(parseInt(val))} />列数值相同的时候,进行单元格合并</div>{/* 这里必须加个key 不然会报错, 社区给的解决方案就是这样的 */}<DndProvider key={Math.random()} backend={HTML5Backend}><Tablecolumns={tableColumns}dataSource={dataSource}pagination={false}components={{body: {row: DraggableBodyRow,},}}onRow={(_, index) => {const attr = {index,moveRow,};return attr as React.HTMLAttributes<any>;}}/></DndProvider></>)default:return <></>}}const getInit = async () => {// console.log(data, "===getInit===");// 过滤掉 操作let newList = data.columns.filter((f: any) => f.id != 'aaa111bbb222ccc333')setDataSource(() => newList)// 配置 table columnssetTableColumns(() => (tableColumns.reduce((preData: any, curData: any) => {return !curData.noRender ? [...preData, curData] : [...preData, {...curData,render: (_: any, record: any, index: any) => {// console.log(_, record, index);// console.log(curData)return <Fragment>{(() => {switch (curData.styleType) {case 'input':return <Input value={record[curData.dataIndex]} onChange={(e) => {setDataSource((dataSource: any) => {let _dataSource = cloneDeep(dataSource)let recordfind = _dataSource.find((f: any) => f.id === record.id)recordfind[curData.dataIndex] = e.target.valuereturn _dataSource})}} placeholder={'请输入'}></Input>case 'checkbox':return <Checkbox onChange={(e) => {setDataSource((dataSource: any) => {let _dataSource = cloneDeep(dataSource)let recordfind = _dataSource.find((f: any) => f.id === record.id)recordfind[curData.dataIndex] = e.target.checkedreturn _dataSource})}} checked={record[curData.dataIndex]}></Checkbox>case 'multipleSelect':return <Selectmode="multiple"allowClearstyle={{ width: '100%' }}defaultValue={record[curData.dataIndex] || []}onChange={(value: any) => {// console.log('%c [multipleSelect value ] 日志', 'font-size:13px; background:#26A08F; color:#fff;', value);// 修改setDataSource((dataSource: any) => {let _dataSource = cloneDeep(dataSource)let recordfind = _dataSource.find((f: any) => f.id === record.id)recordfind[curData.dataIndex] = value// 判断是不是数值类型 赋值样式 目前let numberStyle = ['decimal']let isnumberStyle = data.fields.filter((f: any) => value.includes(f.c)).find((f2: any) => numberStyle.includes(f2.t))if (isnumberStyle) {recordfind.styleType = 'def'} else {recordfind.styleType = 'number'}return _dataSource})}}options={data.fields.map((item: any) => {return {value: item.c,label: item.n,}})}/>case 'select':return <SelectdefaultValue={record[curData.dataIndex] || ''}style={{ width: 120 }}allowClearonChange={(value: any) => {// 修改setDataSource((dataSource: any) => {let _dataSource = cloneDeep(dataSource)let recordfind = _dataSource.find((f: any) => f.id === record.id)recordfind[curData.dataIndex] = valuereturn _dataSource})}}options={[{value: '',label: '无',},{value: 'descend',label: '降序',},{value: 'ascend',label: '升序',},]}/>default:return <div>暂无内容</div>}})()}</Fragment>}}]}, [])))}useEffect(() => {if (!data) returngetInit()}, [])useEffect(() => {// console.log(dataSource, "===dataSource===监听修改");}, [dataSource])return (<><Modalwidth={state.modalWidth}style={{ top: 50 }}destroyOnClose={true}centered={false}title={(() => {return '设置列表'})()}open={data?.isShow}// onOk={onOK}// onCancel={() => setIsShow(false)}footer={(() => {let footer = [<Button key="quxiao3" onClick={() => onOK(0)} size={'large'}>取消</Button>,<Button key="xinzengyitiao" type="primary" onClick={() => addTableRow()} size={'large'}>新增一条</Button>,<Button key="submit" type="primary" onClick={() => onOK(1)} size={'large'}>确定</Button>]return footer})()}maskClosable={false}className="TaskareaTableColumnsCss"closable={false}bodyStyle={{height: state.modalHeight,position: 'relative',display: 'flex',overflow: 'auto',}}><div style={{ width: '100%' }}>{(data?.isShow) && h()}</div></Modal></>);
};
export default index
github:https://github.com/whqgo/ReactAntdTableCustomHeader