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