自定义列功能
需求
表格的列太多,需要实现一个自定义列的功能。
这个自定义列可能被用到多个地方,所以想要做成通用的
思考与实现
那么首先考虑的就是 hooks
, hooks
可以对 columns
进行管理,最后输出一个筛选(自定义)过后的列,组件根据这个列进行渲染。
但是这就有一个问题,对于筛选的这个UI可能也要做成通用的,每个父组件调用下筛选的UI,岂不是很傻。
于是在面临这种既有UI的复用,又有逻辑的复用,hooks
就难以处理了,还是用 render props
来处理。
如下是实现的一个简易自定义列组件。
/*
* @File: 自定义表格列
* @Author: nsne
* @Date: 2020-01-03 15:08:32
* @Last Modified by: nsne
* @Last Modified time: 2020-01-03 17:16:30
* @Usage
*
<CustomColumn columns={props.columns}>
{(columns: ColumnProps<any>[]) => (
<Table
className={`${styles.mTaskTable} ${className}`}
expandRowByClick
expandedRowKeys={expandedRowKeys}
onExpandedRowsChange={onExpandedRowsChange}
{...restProps}
columns={columns}
/>
)}
</CustomColumn>
*
*/
import React, { useState, useEffect } from 'react';
import { Popover, Button, Checkbox } from 'antd';
import { ColumnProps } from 'antd/lib/table';
import _ from 'lodash';
import styles from './index.less';
const CustomColumn = (props: {
columns: ColumnProps<any>[];
defaultColumns?: Array<ColumnProps<any> | string>;
children: (columns) => React.ReactNode;
}) => {
const { columns = [] } = props;
const [column, setColumn] = useState(columns);
const onChange = value => {
const { columns = [] } = props;
const column = columns.filter(
item => value.includes(item.dataIndex) || value.includes(item.title),
);
setColumn(column);
};
let { defaultColumns = [] } = props;
useEffect(() => {
defaultColumns = defaultColumns?.length ? defaultColumns : columns;
const defaultValue = defaultColumns
.map(item => (typeof item === 'string' ? item : item?.dataIndex || _.toString(item?.title)))
.filter(item => column.some(cell => cell.dataIndex === item || cell.title === item));
onChange(defaultValue);
}, []);
const renderContent = () => (
<Checkbox.Group
options={columns?.map((item: ColumnProps<any>, index) => ({
label: item.title || '',
value: item.dataIndex || _.toString(item.title) || index,
}))}
value={column.map(item => item.dataIndex || _.toString(item.title))}
onChange={onChange}
/>
);
return (
<div className={styles.cCustomColumn}>
<Popover
content={renderContent()}
title="请选择要展示的列名"
trigger="click"
overlayClassName={styles.mCustomPopover}
>
<Button icon="setting">自定义列</Button>
</Popover>
{props.children(column)}
</div>
);
};
export default CustomColumn;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。