react antd table 自定义表头功能实现

server/2024/9/24 1:14:54/

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


http://www.ppmy.cn/server/36851.html

相关文章

使用QT开发ROS可视化界面

Q&#xff1a; undefined reference to non-virtual thunk to MyViz A&#xff1a; 该问题主要由于QT中的MOC File没有正确生成&#xff0c;导致虚函数列表出现问题。另外&#xff0c;需要注意虚函数的virtual关键字需要放在类的声明&#xff0c;不能放在类的定义。 qt5_wrap…

Jira Server 不维护了,如何将 Jira 平滑迁移到阿里云云效

作者&#xff1a;天彤 Atlassian 在 2020 年官方发布公告&#xff0c;从 2021 年起停止 Jira Server 产品的销售&#xff0c;并且在 2024 年彻底停止 Server 端产品的服务支持&#xff0c;这对于国内使用 Jira 产品的企业和研发团队造成了不小的影响。而此时国内很多 DevOps 产…

微搭低代码入门06分页查询

目录 1 创建自定义代码2 编写分页代码3 创建页面4 创建变量5 配置数据列表总结 我们在数据模型章节介绍了微搭后端服务编写的三种方式&#xff0c;包括Http请求、自定义代码、云函数。本篇我们详细讲解一下利用自定义代码开发分页查询的功能。 1 创建自定义代码 打开控制台&am…

Python学习笔记(五)——函数和代码得复用

函数的定义与使用 函数的定义 函数是一段代码的表示&#xff0c;也是一段代码的完整封装 -函数是一段具有特定功能的、可重复使用的语句组 -函数是一种功能的抽象&#xff0c;一般函数表达特定功能 -两个作用&#xff1a;降低编码难度和代码复用 def <函数名>(<…

BIGRU、CNN-BIGRU、CNN-BIGRU-ATTENTION、TCN-BIGRU、TCN-BIGRU-ATTENTION合集

&#xff08;BIGRU、CNN-BIGRU、CNN-BIGRU-ATTENTION、TCN-BIGRU、TCN-BIGRU-ATTENTION&#xff09;时&#xff0c;我们可以从它们的基本结构、工作原理、应用场景以及优缺点等方面进行详细介绍和分析。 BIGRU、CNN-BIGRU、CNN-BIGRU-ATTENTION、TCN-BIGRU等&#xff08;matlab…

Spring Cloud 整合Sentinel

1、引入依赖 版本说明 alibaba/spring-cloud-alibaba Wiki GitHub 父pom <spring.cloud.version>Hoxton.SR12</spring.cloud.version> <spring.cloud.alibaba.version>2.2.10-RC1</spring.cloud.alibaba.version>Sentinel应用直接引用starter <…

【JAVA |基础】运算符、程序逻辑控制以及方法的使用

目录 一、前言 二、操作符 1.算术运算符 2.赋值运算符 3.比较运算符 4.逻辑运算符 5.条件&#xff08;三目、三元&#xff09;运算符 6.位运算符(都是基于二进制来计算) 三、 程序逻辑控制 1.顺序结构 2.分支结构 if语句 Switch语句 3.循环结构 while语句 for循环…

Vue3 + Element-plus 报错 require is not defined 处理问题

问题复现&#xff1a; yarn dev 后报错如下&#xff1a; app.js:358 Uncaught ReferenceError: require is not defined at eval (index.mjs:4:30) at Module../node_modules/element-plus/icons-vue/dist/es/index.mjs (chunk-vendors.js:9072:1) at webpack_require (app.j…