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