Table再封装
背景介绍: 业务需要根据后端提供的 JSON 数据渲染报警报表,包括表格的表头,表格数据,表头的模糊筛选(分两种:1 种是输入框模糊查询,另一种是默认值查询。)
先上代码:
frontend/webapp/src/components/Antdd/Table.js
import { useState, useEffect, useRef } from "react";
import { Table, Input } from "antd";
import { SearchOutlined } from "@ant-design/icons";
const Tabled = (props) => {
const [fixedColumns, setFixedColumns] = useState([]);
const inputEl = useRef(null);
/*
设置工单编号可筛选
*/
const getColumnSearchProps = (dataIndex) => ({
filterDropdown: ({
setSelectedKeys,
selectedKeys,
confirm,
clearFilters,
}) => (
<div style={{
padding: 8,
boxShadow: '0 3px 6px -4px rgb(0 0 0 / 12%), 0 6px 16px 0 rgb(0 0 0 / 8%), 0 9px 28px 8px rgb(0 0 0 / 5%)',
position: 'absolute',
width: '244px',
height: '56px',
background: '#fff',
left: '-50px',
top: '-4px'
}}>
<Input
ref={node => {
inputEl.current = node
}}
allowClear
value={selectedKeys[0]}
onChange={(e) => {
setSelectedKeys(e.target.value ? [e.target.value] : []);
// 报表页面删除筛选项 再次展示下拉框没有值
if (props.type === 'statisitcs') {
if (!e.target.value) {
handleSearch([], confirm, dataIndex);
}
}
}}
onPressEnter={() => handleSearch(selectedKeys, confirm, dataIndex)}
style={{ marginBottom: 8, display: "block" }}
addonAfter={
<SearchOutlined
onClick={() => {
handleSearch(selectedKeys, confirm, dataIndex);
}}
/>
}
/>
</div>
),
onFilterDropdownVisibleChange: visible => {
if (visible) {
setTimeout(() => inputEl.current.select(), 100);
}
},
filterIcon: () => (
<SearchOutlined
style={{ color: props.filters[dataIndex] ? "#1890ff" : undefined }}
/>
),
});
const handleSearch = (selectedKeys, confirm, dataIndex) => {
confirm();
const obj = {};
obj[dataIndex] = selectedKeys[0];
props.setFilters({
...props.filters,
page_no: 1,
...obj,
});
};
useEffect(() => {
var result = [];
if (props.sortArr) {
result = props.fixedColumns.map((c) => {
if (props.sortArr.indexOf(c.key) > -1) {
return {
...c,
width: 180,
...getColumnSearchProps(c.key)
}
}
return c;
});
}
if (props.filteredArr && props.filteredArr.length > 0) {
result = result.map((r) => {
const obj = props.filteredArr.find((f) => f.key === r.key);
if (obj) {
return {
...r,
filters: obj.value,
filterMultiple: obj.filterMultiple,
filteredValue: props.filters[obj.key] || null,
};
}
return r;
});
}
if (result.length > 0) {
setFixedColumns(result);
} else {
setFixedColumns(props.fixedColumns);
}
// eslint-disable-next-line
}, [props.sortArr, props.filteredArr, props.total, props.fixedColumns])
useEffect(() => {
// antd Table 在筛选后内容高度小于一屏高度会出现两条滚动条
setTimeout(() => {
if (document.getElementById("BackTopMark")) {
document.getElementById("BackTopMark").scrollTop += 1;
}
}, 300);
}, [props.dataSource]);
const handleTableChange = (pagination, filters, sorter) => {
const obj = {}
let hasChange = false
for (let key in filters) {
// 筛选有值
if (filters[key]) {
obj[key] = filters[key]
} else {
// 有旧值
if (props.filters[key]) {
obj[key] = undefined
}
}
if (filters[key] !== props.filters[key]) {
if (!props.filters[key] && !filters[key]) {
hasChange = false
} else {
hasChange = true
}
}
}
props.setFilters({
...props.filters,
...obj,
page_no: pagination.pageSize !== props.filters.page_size || hasChange ? 1 : pagination.current,
page_size: pagination.pageSize,
})
};
return (
<Table
columns={fixedColumns}
{...props}
scroll={{ x: 1300 }}
sticky={{
getContainer: () => document.getElementById("BackTopMark"),
}}
getPopupContainer={() => document.getElementById("BackTopMark")}
pagination={{
total: props.total,
showSizeChanger: true,
pageSizeOptions: [10, 20, 50, 100],
pageSize: props.filters.page_size,
current: props.filters.page_no,
showTotal: (total, range) =>
`第${range[0]}-${range[1]}行,共${total}行`,
}}
onChange={handleTableChange}
/>
);
};
Tabled.propTypes = Table.propTypes;
Tabled.defaultProps = {
...Table.defaultProps,
};
export default Tabled;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
使用例子:
<Table
rowKey="id"
fixedColumns={columns}
dataSource={dataSource}
sortArr={sortArr}
filteredArr={filteredArr}
setFilters={setFilters}
filters={filters}
total={total}
/>
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
从使用例子中可以看到 Table 组件接受表头,表格数据,筛选数组(分为模糊查询和固定筛选项),filters 为所有筛选字段包括默认筛选字段(比如页面,每页展示条数)。
通过将表格功能的封装,可以只需要在父组件中添加配置就能完成所需功能,极大的提高了开发效率并且需要添加新的功能只需要修改一个文件就能全局应用。
编辑 (opens new window)
上次更新: 2021/08/14, 19:30:57