文章目录
下面是antd 提供的表头筛选网站
https://preview.pro.ant.design/list/table-list?navTheme=light&primaryColor=%231890ff&layout=mix&fixSiderbar=true&title=Ant+Design+Pro
形式如下:
点击表格右上角的设置就可以实现表头字段的筛选
一、通过popover实现下拉菜单组件
(1)基本前端样式
<div>
<Popover placement="bottomRight" trigger="click" content={contentArr}> //这个地方是多选框内容
<Button type="link" className={styles['slect-button']}>
<SettingOutlined />
</Button>
</Popover>
</div>
(2)实现多选
const [checkAll, setCheckAll] = useState(true); //设置是否全选
const [indeterminate, setIndeterminate] = useState(true);//设置是否半选
const contentArr = (
<>
<div className={styles['check-all']}>
//全选onchange
<Checkbox onChange={handleOnchange} checked={checkAll} indeterminate={indeterminate}>
全选
</Checkbox>
</div>
<div className={styles['check-box']}>
<Checkbox.Group
options={arr} //这里的arr是传进来的columns
className={styles['check-box__group']}
onChange={onChildrenChange} //单选onchange
value={value}
/>
</div>
</>
);
(3)设置全选和半选
const handleOnchange = useCallback(
e => {
if (e.target.checked) {
//columns是接受的数据
onChange(columns.map(item => item.key as string));
} else {
onChange([]);
}
setIndeterminate(false);
setCheckAll(e.target.checked);
},
[setCheckAll, columns, onChange],
);
const onChildrenChange = useCallback(
values => {
setIndeterminate(!!values.length && values.length < columns.length);
setCheckAll(values.length === columns.length);
onChange(values);
},
[columns, onChange],
);
(4)源代码
1. 组件代码
完整代码如下:
import { SettingOutlined } from '@ant-design/icons';
import { Button, Checkbox, Popover } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import React, { FC, useCallback, useState, useEffect } from 'react';
import { convertToData } from 'src/utils/covertToCheckData';
import styles from './select-menu.module.scss';
export interface Props {
columns: ColumnsType;
value: string[];
onChange: (value: string[]) => void;
}
const SelectMenu: FC<Props> = ({ columns, value, onChange }): JSX.Element => {
const [checkAll, setCheckAll] = useState(true);
const [indeterminate, setIndeterminate] = useState(true);
//对columns数据进行处理,需要转化成checkbox.group的数据
const arr = convertToData(columns);
const handleOnchange = useCallback(
e => {
if (e.target.checked) {
onChange(columns.map(item => item.key as string));
} else {
onChange([]);
}
setIndeterminate(false);
setCheckAll(e.target.checked);
},
[setCheckAll, columns, onChange],
);
const onChildrenChange = useCallback(
values => {
setIndeterminate(!!values.length && values.length < columns.length);
setCheckAll(values.length === columns.length);
onChange(values);
},
[columns, onChange],
);
useEffect(() => {
setIndeterminate(!!value.length && value.length < columns.length);
}, [value, columns]);
const contentArr = (
<>
<div className={styles['check-all']}>
<Checkbox onChange={handleOnchange} checked={checkAll} indeterminate={indeterminate}>
全选
</Checkbox>
</div>
<div className={styles['check-box']}>
<Checkbox.Group
options={arr}
className={styles['check-box__group']}
onChange={onChildrenChange}
value={value}
/>
</div>
</>
);
return (
<div>
<Popover placement="bottomRight" trigger="click" content={contentArr}>
<Button type="link" className={styles['slect-button']}>
<SettingOutlined />
</Button>
</Popover>
</div>
);
};
export default SelectMenu;
2. scss代码如下:
.slect-button {
color: #333;
font-size: 16px;
float: right;
}
.check-all {
min-height: 32px;
margin: 0;
padding: 5px 1px;
color: rgba(0, 0, 0, 0.85);
font-weight: 500;
border-bottom: 1px solid #f0f0f0;
}
.check-box {
padding-top: 6px;
padding-left: 10px;
&__group {
display: flex;
flex-direction: column;
line-height: 1.8;
}
}
3. 转化columns的函数
export function convertToData(list: any[]) {
list.forEach(item => {
item.label = item.title;
item.value = item.key;
});
return list;
}
4. 最终实现结果
二、页面组件基本使用
<div>
<SelectMenu//组件调用
columns={columns} //传入基本的columns
onChange={selectMenuList.onchange} //hooks参考第三点
value={selectMenuList.colValue}。 //hooks参考第三点
/>
<Table
dataSource={list}
rowKey="id"
columns={selectMenuList.columnsData}。//hooks参考第三点
scroll={{ x: 1500, y: 1000 }}
pagination={{
pageSize,
total,
current: pageIndex,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '30'],
}}
onChange={handlePaginationChange}
/>
</div>
三、hooks处理table columns数据
(1)hooks封装
因为前端页面肯定不是这一个页面使用,减少重复代码使用hooks进行配置:
import { ColumnsType } from 'antd/lib/table';
import { useCallback, useState } from 'react';
export const useSelectMenu = (columns: ColumnsType) => {
//这个是checkbox选中下的value,默认是全部
const [colValue, setColValue] = useState<string[]>(columns.map(item => item.key as string));
//这个是在所有的columns中过滤出选中的数据
const columnsData = columns.filter(item => colValue.includes(item.key as string));
//当change函数调用时set进去被选中的数据
const onchange = useCallback(values => {
setColValue(values);
}, []);
return {
colValue,
columnsData,
onchange,
};
};
(2)hooks 的使用
const selectMenuList = useSelectMenu(columns);