基于antd 实现
表格要实现多个多选互不影响包含 全选 半选 。(可自由拓展)
import { Checkbox, Table } from 'antd';
import React, { useEffect, useState } from 'react';
const MultipleMultipleTables: React.FC<any> = (props: any) => {
/**
* 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 = () => {
let trueArr: any = {};
let checkAll = {};
let 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: { [x: string]: any }) => item);
}
return checkAll;
};
//全选 必须对应 表格内容数据的
const [checkAll, setCheckAll] = useState<any>(checkAllFun()),
//表格数据
[data, setData] = useState(dataList),
//全选属性
[typeNext, setTypeNext] = useState('');
//监听数据变化
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, index: 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: any, record: { enabled: boolean | undefined }, index: any) => {
return (
<>
<Checkbox
onChange={(e) => onCheckAllChange(e, record, item)}
checked={record[item]}
// disabled={disabled || !record['is' + item]} 控制字段不可选
></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: { [x: string]: any }) => 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)
: '';
return item;
});
});
setTypeNext('string' == typeof recordAndType ? recordAndType : type);
};
return (
<>
<Table rowKey={rowKey || 'id'} columns={columns} dataSource={data} />
</>
);
};
export default MultipleMultipleTables;
如果想禁用不可选择可以 通过在数据添加 字段 isXXX
disabled={disabled || !record['is' + item]}
import {Table } from 'antd';
import MultipleMultipleTables from './components/MultipleMultipleTables';
// 模拟接口数据 表格内容数据
const 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',
},
];
const onChangeDataList = (dataList: any) => {
console.log(dataList, '====父组件data======');
};
const SettingRoleRightsDetails: React.FC<{}> = (props: any) => {
const [datas, setDatas] = useState(dataList);
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 SettingRoleRightsDetails;