1
2
<template>
<div
vben
authored
5 years ago
3
ref="wrapRef"
4
5
6
class="basic-table"
:class="{
'table-form-container': getBindValues.useSearchForm,
vben
authored
5 years ago
7
inset: getBindValues.inset,
8
9
10
}"
>
<BasicForm
vben
authored
5 years ago
11
:submitOnReset="true"
12
13
14
v-bind="getFormProps"
v-if="getBindValues.useSearchForm"
:submitButtonOptions="{ loading }"
vben
authored
5 years ago
15
:tableAction="tableAction"
16
17
18
19
20
21
22
23
24
25
@register="registerForm"
@submit="handleSearchInfoChange"
@advanced-change="redoHeight"
>
<template #[item]="data" v-for="item in Object.keys($slots)">
<slot :name="`form-${item}`" v-bind="data" />
</template>
</BasicForm>
<Table
ref="tableElRef"
vben
authored
5 years ago
26
v-bind="getBindValues"
vben
authored
5 years ago
27
:rowClassName="getRowClassName"
vben
authored
5 years ago
28
v-show="getEmptyDataIsShowTable"
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@change="handleTableChange"
>
<template #[item]="data" v-for="item in Object.keys($slots)">
<slot :name="item" v-bind="data" />
</template>
</Table>
</div>
</template>
<script lang="ts">
import type {
BasicTableProps,
FetchParams,
GetColumnsParams,
TableActionType,
vben
authored
5 years ago
43
SizeType,
vben
authored
5 years ago
44
45
SorterResult,
TableCustomRecord,
46
} from './types/table';
vben
authored
5 years ago
47
import { PaginationProps } from './types/pagination';
vben
authored
5 years ago
48
vben
authored
5 years ago
49
50
import { defineComponent, ref, computed, unref, watch, nextTick, toRaw } from 'vue';
import { Table } from 'ant-design-vue';
51
52
53
import renderTitle from './components/renderTitle';
import renderFooter from './components/renderFooter';
import renderExpandIcon from './components/renderExpandIcon';
vben
authored
5 years ago
54
55
56
57
58
import { BasicForm, FormProps, useForm } from '/@/components/Form/index';
import { isFunction, isString } from '/@/utils/is';
import { deepMerge } from '/@/utils';
import { omit } from 'lodash-es';
59
60
61
62
63
64
65
66
import { usePagination } from './hooks/usePagination';
import { useColumns } from './hooks/useColumns';
import { useDataSource } from './hooks/useDataSource';
import { useLoading } from './hooks/useLoading';
import { useRowSelection } from './hooks/useRowSelection';
import { useTableScroll } from './hooks/useTableScroll';
import { provideTable } from './hooks/useProvinceTable';
vben
authored
5 years ago
67
vben
authored
5 years ago
68
import { useEventListener } from '/@/hooks/event/useEventListener';
vben
authored
5 years ago
69
70
import { basicProps } from './props';
import { ROW_KEY } from './const';
vben
authored
5 years ago
71
import './style/index.less';
72
73
74
75
76
77
export default defineComponent({
props: basicProps,
components: { Table, BasicForm },
emits: ['fetch-success', 'fetch-error', 'selection-change', 'register'],
setup(props, { attrs, emit, slots }) {
const tableElRef = ref<any>(null);
vben
authored
5 years ago
78
const wrapRef = ref<Nullable<HTMLDivElement>>(null);
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
const innerPropsRef = ref<Partial<BasicTableProps>>();
const [registerForm, { getFieldsValue }] = useForm();
const getMergeProps = computed(
(): BasicTableProps => {
return {
...props,
...unref(innerPropsRef),
} as BasicTableProps;
}
);
const { loadingRef } = useLoading(getMergeProps);
const { getPaginationRef, setPagination } = usePagination(getMergeProps);
const { getColumnsRef, setColumns } = useColumns(getMergeProps, getPaginationRef);
const { getDataSourceRef, setTableData, fetch, getAutoCreateKey } = useDataSource(
getMergeProps,
{
getPaginationRef,
loadingRef,
setPagination,
getFieldsValue,
},
emit
);
vben
authored
5 years ago
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
const { getScrollRef, redoHeight } = useTableScroll(getMergeProps, tableElRef);
const {
getRowSelectionRef,
getSelectRows,
clearSelectedRowKeys,
getSelectRowKeys,
deleteSelectRowByKey,
setSelectedRowKeys,
} = useRowSelection(getMergeProps, emit);
const getRowKey = computed(() => {
const { rowKey } = unref(getMergeProps);
return unref(getAutoCreateKey) ? ROW_KEY : rowKey;
});
vben
authored
5 years ago
119
120
const getBindValues = computed(() => {
vben
authored
5 years ago
121
122
123
124
const { title, titleHelpMessage, showSummary, showTableSetting, tableSetting } = unref(
getMergeProps
);
const hideTitle = !slots.tableTitle && !title && !slots.toolbar && !showTableSetting;
125
const titleData: any =
vben
authored
5 years ago
126
hideTitle && !isString(title)
127
128
? {}
: {
vben
authored
5 years ago
129
130
131
132
133
134
135
136
137
138
title: hideTitle
? null
: renderTitle.bind(
null,
title,
titleHelpMessage,
slots,
showTableSetting,
tableSetting
),
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
};
const pagination = unref(getPaginationRef);
const rowSelection = unref(getRowSelectionRef);
const scroll = unref(getScrollRef);
const loading = unref(loadingRef);
const rowKey = unref(getRowKey);
const columns = unref(getColumnsRef);
const dataSource = unref(getDataSourceRef);
let propsData = {
size: 'middle',
...(slots.expandedRowRender ? { expandIcon: renderExpandIcon() } : {}),
...attrs,
...unref(getMergeProps),
...titleData,
scroll,
loading,
tableLayout: 'fixed',
rowSelection,
rowKey,
columns,
pagination,
dataSource,
};
if (slots.expandedRowRender) {
propsData = omit(propsData, 'scroll');
}
if (showSummary) {
propsData.footer = renderFooter.bind(null, {
vben
authored
5 years ago
167
scroll: scroll as any,
168
169
170
171
172
173
174
175
columnsRef: getColumnsRef,
summaryFunc: unref(getMergeProps).summaryFunc,
dataSourceRef: getDataSourceRef,
rowSelectionRef: getRowSelectionRef,
});
}
return propsData;
});
vben
authored
5 years ago
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
const getFormProps = computed(() => {
const { formConfig } = unref(getBindValues);
const formProps: FormProps = {
showAdvancedButton: true,
...(formConfig as FormProps),
compact: true,
};
return formProps;
});
const getEmptyDataIsShowTable = computed(() => {
const { emptyDataIsShowTable, useSearchForm } = unref(getMergeProps);
if (emptyDataIsShowTable || !useSearchForm) {
return true;
}
return !!unref(getDataSourceRef).length;
});
vben
authored
5 years ago
195
196
197
198
199
200
201
202
watch(
() => unref(getDataSourceRef),
() => {
handleSummary();
},
{ immediate: true }
);
vben
authored
5 years ago
203
function getRowClassName(record: TableCustomRecord, index: number) {
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
const { striped, rowClassName } = unref(getMergeProps);
if (!striped) return;
if (rowClassName && isFunction(rowClassName)) {
return rowClassName(record);
}
return (index || 0) % 2 === 1 ? 'basic-table-row__striped' : '';
}
function handleSearchInfoChange(info: any) {
const { handleSearchInfoFn } = unref(getMergeProps);
if (handleSearchInfoFn && isFunction(handleSearchInfoFn)) {
info = handleSearchInfoFn(info) || info;
}
fetch({ searchInfo: info, page: 1 });
}
vben
authored
5 years ago
220
221
function handleTableChange(
pagination: PaginationProps,
vben
authored
5 years ago
222
// @ts-ignore
vben
authored
5 years ago
223
filters: Partial<Record<string, string[]>>,
vben
authored
5 years ago
224
sorter: SorterResult
vben
authored
5 years ago
225
226
) {
const { clearSelectOnPageChange, sortFn } = unref(getMergeProps);
227
228
229
230
if (clearSelectOnPageChange) {
clearSelectedRowKeys();
}
setPagination(pagination);
vben
authored
5 years ago
231
232
233
234
235
236
if (sorter && isFunction(sortFn)) {
const sortInfo = sortFn(sorter);
fetch({ sortInfo });
return;
}
237
238
fetch();
}
vben
authored
5 years ago
239
vben
authored
5 years ago
240
241
242
243
244
245
246
247
248
function handleSummary() {
if (unref(getMergeProps).showSummary) {
nextTick(() => {
const tableEl = unref(tableElRef);
if (!tableEl) {
return;
}
const bodyDomList = tableEl.$el.querySelectorAll('.ant-table-body') as HTMLDivElement[];
const bodyDom = bodyDomList[0];
vben
authored
5 years ago
249
useEventListener({
vben
authored
5 years ago
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
el: bodyDom,
name: 'scroll',
listener: () => {
const footerBodyDom = tableEl.$el.querySelector(
'.ant-table-footer .ant-table-body'
) as HTMLDivElement;
if (!footerBodyDom || !bodyDom) return;
footerBodyDom.scrollLeft = bodyDom.scrollLeft;
},
wait: 0,
options: true,
});
});
}
}
vben
authored
5 years ago
266
267
268
269
function setProps(props: Partial<BasicTableProps>) {
innerPropsRef.value = deepMerge(unref(innerPropsRef) || {}, props);
}
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
const tableAction: TableActionType = {
reload: async (opt?: FetchParams) => {
await fetch(opt);
},
getSelectRows,
clearSelectedRowKeys,
getSelectRowKeys,
deleteSelectRowByKey,
setPagination,
setTableData,
redoHeight,
setSelectedRowKeys,
setColumns,
getPaginationRef: () => {
return unref(getPaginationRef);
},
getColumns: (opt?: GetColumnsParams) => {
vben
authored
5 years ago
287
288
const { ignoreIndex, ignoreAction } = opt || {};
let columns = toRaw(unref(getColumnsRef));
289
290
291
if (ignoreIndex) {
columns = columns.filter((item) => item.flag !== 'INDEX');
}
vben
authored
5 years ago
292
293
294
if (ignoreAction) {
columns = columns.filter((item) => item.flag !== 'ACTION');
}
295
296
297
298
299
300
301
302
return columns;
},
getDataSource: () => {
return unref(getDataSourceRef);
},
setLoading: (loading: boolean) => {
loadingRef.value = loading;
},
vben
authored
5 years ago
303
304
305
setProps,
getSize: (): SizeType => {
return unref(getBindValues).size;
306
307
308
},
};
vben
authored
5 years ago
309
310
311
312
provideTable({
...tableAction,
wrapRef,
});
313
314
315
316
317
318
319
320
321
322
323
324
emit('register', tableAction);
return {
tableElRef,
getBindValues,
loading: loadingRef,
registerForm,
handleSearchInfoChange,
getFormProps,
getEmptyDataIsShowTable,
handleTableChange,
getRowClassName,
vben
authored
5 years ago
325
wrapRef,
vben
authored
5 years ago
326
tableAction,
327
328
329
330
331
...tableAction,
};
},
});
</script>