Lowell
2021-07-25 98c206d9c9661a18dde4ec7782cbe1eb6e62ebeb
提交 | 用户 | age
faf3f4 1 <template>
391da9 2   <div ref="wrapRef" :class="getWrapperClass">
faf3f4 3     <BasicForm
116a1f 4       submitOnReset
faf3f4 5       v-bind="getFormProps"
6       v-if="getBindValues.useSearchForm"
5832ee 7       :tableAction="tableAction"
faf3f4 8       @register="registerForm"
9       @submit="handleSearchInfoChange"
10       @advanced-change="redoHeight"
11     >
116a1f 12       <template #[replaceFormSlotKey(item)]="data" v-for="item in getFormSlotKeys">
9edc28 13         <slot :name="item" v-bind="data"></slot>
faf3f4 14       </template>
15     </BasicForm>
116a1f 16
faf3f4 17     <Table
18       ref="tableElRef"
84b830 19       v-bind="getBindValues"
a1ffb6 20       :rowClassName="getRowClassName"
84b830 21       v-show="getEmptyDataIsShowTable"
faf3f4 22       @change="handleTableChange"
23     >
391da9 24       <template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
9edc28 25         <slot :name="item" v-bind="data"></slot>
faf3f4 26       </template>
391da9 27
9c2f3f 28       <template #[`header-${column.dataIndex}`] v-for="column in columns" :key="column.dataIndex">
V 29         <HeaderCell :column="column" />
30       </template>
faf3f4 31     </Table>
32   </div>
33 </template>
34 <script lang="ts">
125a7d 35   import type {
36     BasicTableProps,
37     TableActionType,
38     SizeType,
39     ColumnChangeParam,
40   } from './types/table';
8b3a4d 41
e09068 42   import { defineComponent, ref, computed, unref, toRaw } from 'vue';
a1ffb6 43   import { Table } from 'ant-design-vue';
116a1f 44   import { BasicForm, useForm } from '/@/components/Form/index';
391da9 45   import expandIcon from './components/ExpandIcon';
V 46   import HeaderCell from './components/HeaderCell.vue';
125a7d 47   import { InnerHandlers } from './types/table';
faf3f4 48
49   import { usePagination } from './hooks/usePagination';
50   import { useColumns } from './hooks/useColumns';
51   import { useDataSource } from './hooks/useDataSource';
52   import { useLoading } from './hooks/useLoading';
53   import { useRowSelection } from './hooks/useRowSelection';
54   import { useTableScroll } from './hooks/useTableScroll';
354904 55   import { useCustomRow } from './hooks/useCustomRow';
V 56   import { useTableStyle } from './hooks/useTableStyle';
116a1f 57   import { useTableHeader } from './hooks/useTableHeader';
391da9 58   import { useTableExpand } from './hooks/useTableExpand';
116a1f 59   import { createTableContext } from './hooks/useTableContext';
V 60   import { useTableFooter } from './hooks/useTableFooter';
61   import { useTableForm } from './hooks/useTableForm';
9c2f3f 62   import { useDesign } from '/@/hooks/web/useDesign';
8b3a4d 63
391da9 64   import { omit } from 'lodash-es';
a1ffb6 65   import { basicProps } from './props';
9f5085 66   import { isFunction } from '/@/utils/is';
a305e5 67
faf3f4 68   export default defineComponent({
9c2f3f 69     components: {
V 70       Table,
71       BasicForm,
2c6aa8 72       HeaderCell,
9c2f3f 73     },
9edc28 74     props: basicProps,
354904 75     emits: [
V 76       'fetch-success',
77       'fetch-error',
78       'selection-change',
79       'register',
80       'row-click',
81       'row-dbClick',
82       'row-contextmenu',
83       'row-mouseenter',
84       'row-mouseleave',
9c2f3f 85       'edit-end',
V 86       'edit-cancel',
de5bf7 87       'edit-row-end',
4f8e1c 88       'edit-change',
391da9 89       'expanded-rows-change',
9f4d17 90       'change',
125a7d 91       'columns-change',
354904 92     ],
bd2039 93     setup(props, { attrs, emit, slots, expose }) {
6e03e0 94       const tableElRef = ref<ComponentRef>(null);
601368 95       const tableData = ref<Recordable[]>([]);
354904 96
8b3a4d 97       const wrapRef = ref<Nullable<HTMLDivElement>>(null);
faf3f4 98       const innerPropsRef = ref<Partial<BasicTableProps>>();
354904 99
116a1f 100       const { prefixCls } = useDesign('basic-table');
V 101       const [registerForm, formActions] = useForm();
faf3f4 102
354904 103       const getProps = computed(() => {
V 104         return { ...props, ...unref(innerPropsRef) } as BasicTableProps;
08df19 105       });
a305e5 106
354904 107       const { getLoading, setLoading } = useLoading(getProps);
a2c89d 108       const {
V 109         getPaginationInfo,
110         getPagination,
111         setPagination,
112         setShowPagination,
113         getShowPagination,
114       } = usePagination(getProps);
8b3a4d 115
faf3f4 116       const {
116a1f 117         getRowSelection,
faf3f4 118         getRowSelectionRef,
119         getSelectRows,
120         clearSelectedRowKeys,
121         getSelectRowKeys,
122         deleteSelectRowByKey,
123         setSelectedRowKeys,
601368 124       } = useRowSelection(getProps, tableData, emit);
9c2f3f 125
V 126       const {
9f4d17 127         handleTableChange: onTableChange,
9c2f3f 128         getDataSourceRef,
V 129         getDataSource,
130         setTableData,
8e4f48 131         updateTableDataRecord,
9c2f3f 132         fetch,
V 133         getRowKey,
134         reload,
135         getAutoCreateKey,
136         updateTableData,
137       } = useDataSource(
138         getProps,
139         {
601368 140           tableData,
9c2f3f 141           getPaginationInfo,
V 142           setLoading,
143           setPagination,
144           getFieldsValue: formActions.getFieldsValue,
145           clearSelectedRowKeys,
146         },
147         emit
148       );
9f4d17 149
150       function handleTableChange(...args) {
151         onTableChange.call(undefined, ...args);
152         emit('change', ...args);
9f5085 153         // 解决通过useTable注册onChange时不起作用的问题
154         const { onChange } = unref(getProps);
155         onChange && isFunction(onChange) && onChange.call(undefined, ...args);
9f4d17 156       }
9c2f3f 157
c96002 158       const {
V 159         getViewColumns,
160         getColumns,
161         setCacheColumnsByField,
162         setColumns,
163         getColumnsRef,
164         getCacheColumns,
165       } = useColumns(getProps, getPaginationInfo);
116a1f 166
V 167       const { getScrollRef, redoHeight } = useTableScroll(
168         getProps,
169         tableElRef,
170         getColumnsRef,
53867a 171         getRowSelectionRef,
V 172         getDataSourceRef
116a1f 173       );
faf3f4 174
354904 175       const { customRow } = useCustomRow(getProps, {
V 176         setSelectedRowKeys,
177         getSelectRowKeys,
178         clearSelectedRowKeys,
179         getAutoCreateKey,
180         emit,
faf3f4 181       });
8b3a4d 182
116a1f 183       const { getRowClassName } = useTableStyle(getProps, prefixCls);
354904 184
391da9 185       const { getExpandOption, expandAll, collapseAll } = useTableExpand(getProps, tableData, emit);
V 186
125a7d 187       const handlers: InnerHandlers = {
188         onColumnsChange: (data: ColumnChangeParam[]) => {
189           emit('columns-change', data);
190           // support useTable
191           unref(getProps).onColumnsChange?.(data);
192         },
193       };
194
195       const { getHeaderProps } = useTableHeader(getProps, slots, handlers);
116a1f 196
V 197       const { getFooterProps } = useTableFooter(
198         getProps,
199         getScrollRef,
200         tableElRef,
201         getDataSourceRef
354904 202       );
V 203
0e440f 204       const { getFormProps, replaceFormSlotKey, getFormSlotKeys, handleSearchInfoChange } =
M 205         useTableForm(getProps, slots, fetch, getLoading);
354904 206
116a1f 207       const getBindValues = computed(() => {
b54b79 208         const dataSource = unref(getDataSourceRef);
354904 209         let propsData: Recordable = {
faf3f4 210           size: 'middle',
37f666 211           // ...(dataSource.length === 0 ? { getPopupContainer: () => document.body } : {}),
faf3f4 212           ...attrs,
354904 213           customRow,
98c206 214           expandIcon: slots.expandIcon ? null : expandIcon(),
354904 215           ...unref(getProps),
116a1f 216           ...unref(getHeaderProps),
354904 217           scroll: unref(getScrollRef),
V 218           loading: unref(getLoading),
faf3f4 219           tableLayout: 'fixed',
354904 220           rowSelection: unref(getRowSelectionRef),
V 221           rowKey: unref(getRowKey),
e09068 222           columns: toRaw(unref(getViewColumns)),
V 223           pagination: toRaw(unref(getPaginationInfo)),
37f666 224           dataSource,
116a1f 225           footer: unref(getFooterProps),
391da9 226           ...unref(getExpandOption),
faf3f4 227         };
228         if (slots.expandedRowRender) {
229           propsData = omit(propsData, 'scroll');
230         }
a3a903 231
9f4d17 232         propsData = omit(propsData, ['class', 'onChange']);
faf3f4 233         return propsData;
391da9 234       });
V 235
236       const getWrapperClass = computed(() => {
237         const values = unref(getBindValues);
238         return [
239           prefixCls,
240           attrs.class,
241           {
242             [`${prefixCls}-form-container`]: values.useSearchForm,
243             [`${prefixCls}--inset`]: values.inset,
244           },
245         ];
faf3f4 246       });
247
248       const getEmptyDataIsShowTable = computed(() => {
354904 249         const { emptyDataIsShowTable, useSearchForm } = unref(getProps);
faf3f4 250         if (emptyDataIsShowTable || !useSearchForm) {
251           return true;
252         }
253         return !!unref(getDataSourceRef).length;
254       });
8b3a4d 255
V 256       function setProps(props: Partial<BasicTableProps>) {
116a1f 257         innerPropsRef.value = { ...unref(innerPropsRef), ...props };
8b3a4d 258       }
V 259
faf3f4 260       const tableAction: TableActionType = {
354904 261         reload,
faf3f4 262         getSelectRows,
263         clearSelectedRowKeys,
264         getSelectRowKeys,
265         deleteSelectRowByKey,
266         setPagination,
267         setTableData,
8e4f48 268         updateTableDataRecord,
faf3f4 269         redoHeight,
270         setSelectedRowKeys,
271         setColumns,
354904 272         setLoading,
V 273         getDataSource,
8b3a4d 274         setProps,
116a1f 275         getRowSelection,
354904 276         getPaginationRef: getPagination,
V 277         getColumns,
116a1f 278         getCacheColumns,
9c2f3f 279         emit,
V 280         updateTableData,
a2c89d 281         setShowPagination,
V 282         getShowPagination,
c96002 283         setCacheColumnsByField,
391da9 284         expandAll,
V 285         collapseAll,
a305e5 286         getSize: () => {
V 287           return unref(getBindValues).size as SizeType;
faf3f4 288         },
289       };
116a1f 290       createTableContext({ ...tableAction, wrapRef, getBindValues });
faf3f4 291
bd2039 292       expose(tableAction);
9bb751 293
116a1f 294       emit('register', tableAction, formActions);
08df19 295
faf3f4 296       return {
297         tableElRef,
298         getBindValues,
354904 299         getLoading,
faf3f4 300         registerForm,
301         handleSearchInfoChange,
302         getEmptyDataIsShowTable,
303         handleTableChange,
304         getRowClassName,
8b3a4d 305         wrapRef,
5832ee 306         tableAction,
9bb751 307         redoHeight,
116a1f 308         getFormProps,
V 309         replaceFormSlotKey,
310         getFormSlotKeys,
391da9 311         getWrapperClass,
9c2f3f 312         columns: getViewColumns,
faf3f4 313       };
314     },
315   });
316 </script>
391da9 317 <style lang="less">
V 318   @border-color: #cecece4d;
319
320   @prefix-cls: ~'@{namespace}-basic-table';
321
322   .@{prefix-cls} {
d73d43 323     max-width: 100%;
V 324
e1bc33 325     &-row__striped {
V 326       td {
0e440f 327         background-color: @app-content-background;
e1bc33 328       }
V 329     }
330
391da9 331     &-form-container {
V 332       padding: 16px;
333
334       .ant-form {
335         padding: 12px 10px 6px 10px;
336         margin-bottom: 16px;
2cdf2c 337         background-color: @component-background;
e2ddf4 338         border-radius: 2px;
391da9 339       }
V 340     }
341
342     &--inset {
343       .ant-table-wrapper {
344         padding: 0;
345       }
346     }
347
348     .ant-tag {
349       margin-right: 0;
350     }
351
352     .ant-table-wrapper {
353       padding: 6px;
2cdf2c 354       background-color: @component-background;
391da9 355       border-radius: 2px;
V 356
357       .ant-table-title {
bf365e 358         min-height: 40px;
391da9 359         padding: 0 0 8px 0 !important;
V 360       }
361
362       .ant-table.ant-table-bordered .ant-table-title {
363         border: none !important;
364       }
365     }
366
367     .ant-table {
368       width: 100%;
369       overflow-x: hidden;
370
371       &-title {
372         display: flex;
373         padding: 8px 6px;
374         border-bottom: none;
375         justify-content: space-between;
376         align-items: center;
377       }
378
379       .ant-table-tbody > tr.ant-table-row-selected td {
2cdf2c 380         background-color: fade(@primary-color, 8%) !important;
391da9 381       }
V 382     }
383
384     .ant-pagination {
385       margin: 10px 0 0 0;
386     }
387
388     .ant-table-footer {
389       padding: 0;
390
391       .ant-table-wrapper {
392         padding: 0;
393       }
394
395       table {
396         border: none !important;
397       }
398
399       .ant-table-body {
400         overflow-x: hidden !important;
401         overflow-y: scroll !important;
402       }
403
404       td {
405         padding: 12px 8px;
406       }
407     }
408   }
409 </style>