react antd 有多列 checkbox,并且更改选中后的文本
需求中需要批量对一些数据进行批量设置,将数组对象数据再次调取接口
antd tabel表格本身不支持,经过不懈努力,及参考网上大佬做法,对antd表格进行改良,满足自己一些略小的需求,没有过于复杂的逻辑交互,单纯操控数据
先上图,
先展示列表数据,将选中的数据,点击上侧的按钮,将对应得数据,刷成当前的文本,并由一个保存按钮,将当前的数据传到后端
上代码 -checkTable组件
import { Checkbox, Table, Button } from 'antd';
import React, { useEffect, useState } from 'react';
/* eslint-disable */
const MultipleMultipleTables: React.FC<CommonObjectType> = (props) => {
/**
* Array- dataList 表格数据
* Object- checkAllList 多选字段全选
* String- rowKey 主键 默认 id
* String- showField 需要展示的字段 字符串 使用 空格 隔开
* Object- checkAllTitle 多选字段名称表头 不传 为空 对应 showField 表头
* func- onChangeDataList 事件 返回 当前改变的数据
*/
const { dataList, checkAllList, rowKey, showField, checkAllTitle, onChangeDataList } = props;
//表格数据
// let dataList = [
// {
// id: '1',
// c: '按钮权限',
// age: 32,
// enabled: true,
// editor: false,
// del: false,
// name: '大王',
// },
// {
// id: '2',
// c: 'Jim Green',
// age: 42,
// enabled: true,
// editor: true,
// del: false,
// name: '大王1',
// },
// {
// id: '3',
// c: 'Joe Black',
// age: 32,
// enabled: true,
// editor: true,
// del: false,
// name: '大王2',
// },
// ];
//设置 全选的 字段 必填 对应数据 控制的字段
// let checkAllList = {
// enabled: null,
// editor: null,
// };
/**
* @description: 初始化 全选默认值 根据 dataList和checkAllList 设置
* @param {*}
* @return {*}
*/
const checkAllFun = () => {
const trueArr = {};
const checkAll = {};
const checkAllKeys = Object.keys(checkAllList);
for (const iKey of checkAllKeys) {
for (const i in dataList) {
if (!trueArr[iKey]) trueArr[iKey] = [];
trueArr[iKey].push(dataList[i][iKey]);
}
}
for (const key in trueArr) {
checkAll[key] = trueArr[key].every((item: CommonObjectType) => item);
}
return checkAll;
};
//全选 必须对应 表格内容数据的
const [checkAll, setCheckAll] = useState<any>(checkAllFun()),
//表格数据
[data, setData] = useState(dataList),
//全选属性
[typeNext, setTypeNext] = useState('');
//监听父组件的参数,实时更新数据
useEffeect(()=>{
setData(dataList)
},[dataList])
//监听数据变化
useEffect(() => {
//设置当前点击的 是否全选
if (!typeNext) return;
setCheckAll(() => {
return {
...checkAll,
[typeNext]: data.every((item: { [x: string]: any }) => item[typeNext])
};
});
//每次有效操作会传递给父组件
if (onChangeDataList) onChangeDataList(data);
}, [data, typeNext]);
//全选 必须对应 表格内容数据的 类型状态多选字段 生成 columns
const columnsFun = () => {
if (!showField) return;
const columns: any = [];
const field = showField.split(' ');
field.map((item: any) => {
if (Object.keys(checkAll).includes(item)) {
let multiple = {
title: () => {
return (
<Checkbox
indeterminate={indeterminateFun(item)}
onChange={(e) => onCheckAllChange(e, item)}
checked={checkAll[item]}
>
{checkAllTitle[item] || ''}
</Checkbox>
);
},
dataIndex: item,
render: (text, record: { enabled: boolean | undefined }) => {
return (
<>
<Checkbox onChange={(e) => onCheckAllChange(e, record, item)} checked={record[item]}>
{record[`${item}` + 'Name'] ? record[`${item}` + 'Name'] : '-'}
</Checkbox>
</>
);
}
};
columns.push(multiple);
} else {
columns.push({
title: checkAllTitle[item],
dataIndex: item
});
}
});
return columns;
};
const columns = columnsFun();
/**
* @description: 半选的状态 表达式
* 当前全选 为true 半选为 false
* 当前全选 为false 半选 判断当前是否有选中项 有就返回true
* @param {any} type 全选的类型
* @return {*}
*/
const indeterminateFun = (type?: any) => {
let indeterminate = data.some((someItem: CommonObjectType) => someItem[type]);
return (checkAll[type] && !indeterminate) || (!checkAll[type] && indeterminate);
};
/**
* @description: 当为三个参数的时候 处理的是 子复选框 当为俩参数的时候 为全选的复选框
* @param {any} e 事件 获取当前选择的状态
* @param {any} recordAndType 当前数据或者选择类型
* @param {any} type 类型
* @return {*}
*/
const onCheckAllChange = (e: any, recordAndType?: any, type?: any) => {
setData(() => {
return data.map((item: any) => {
// 'string' == typeof recordAndType
// ? (item[recordAndType] = e.target.checked)
// : item.id == recordAndType.id
// ? (item[type] = e.target.checked)
// : '';
if (typeof recordAndType === 'string') {
item[recordAndType] = e.target.checked;
} else {
if (item.id === recordAndType.id) {
item[type] = e.target.checked;
}
}
return item;
});
});
setTypeNext('string' == typeof recordAndType ? recordAndType : type);
};
const handleNo = (text) => {
handleCommon(text);
};
const handleCommon = (text) => {
// console.log(data, dataList, checkAllList, 'aaaaaaaaaaaaa');
Object.keys(checkAllList).forEach((item) => {
dataList.forEach((ite) => {
// if(ite[item])
if (ite[item] === true) {
// `${ite[item] + 'Name'}` = '我是李';
ite[`${item}` + 'Name'] = text;
ite[item] = false;
}
});
});
//修复操作完 check的半取消状态
setCheckAll({ permissionDone: false, permissionPrepare: false, permissionReturn: false, permissionUnder: false });
setData(dataList);
};
return (
<>
<div>
<Button onClick={() => handleNo('不可见')}>不可见</Button>
<Button onClick={() => handleNo('数据不可见')}>数据不可见</Button>
<Button onClick={() => handleNo('只读')}>只读</Button>
<Button onClick={() => handleNo('可编辑')}>可编辑</Button>
</div>
<Table rowKey={rowKey || 'id'} columns={columns} dataSource={data} />
</>
);
};
export default MultipleMultipleTables;
父组件调用
import React, { FC, useState } from 'react';
import MultipleMultipleTables from './multTable';
const Power: FC = () => {
// 模拟接口数据 表格内容数据
const dataList = [
{
id: '1',
c: '按钮权限',
age: 32,
enabled: false,
enabledName: '222',
editor: false,
del: false,
name: '大王'
},
{
id: '2',
c: 'Jim Green',
age: 42,
enabled: false,
enabledName: '44444444',
editor: false,
del: false,
name: '大王1'
},
{
id: '3',
c: 'Joe Black',
age: 32,
enabled: false,
enabledName: '555555555',
editor: false,
del: false,
name: '大王2'
}
];
const [datas, setDatas] = useState(dataList);
const onChangeDataList = (dataList: any, recordAndType, type) => {
console.log(dataList, recordAndType, type, '====父组件data======');
// const arr = dataList.map((item) => {
// return {
// ...item,
// enabledName: Math.floor(Math.random() * 10 + 1)
// };
// });
// setDatas(arr);
};
return (
<div>
权限配置
<MultipleMultipleTables
dataList={datas}
showField="c age enabled editor"
checkAllList={{ enabled: null, editor: null }}
checkAllTitle={{ c: '名称', age: '年龄', enabled: '是否可用', editor: '是否可编辑' }}
onChangeDataList={onChangeDataList}
></MultipleMultipleTables>
</div>
);
};
export default Power;
主要参考这个来写的,
链接: link