Blame view

src/components/Table/src/BasicTable.vue 10.1 KB
1
2
<template>
  <div
vben authored
3
    ref="wrapRef"
4
5
6
    class="basic-table"
    :class="{
      'table-form-container': getBindValues.useSearchForm,
7
      inset: getBindValues.inset,
8
9
10
    }"
  >
    <BasicForm
11
      :submitOnReset="true"
12
13
14
      v-bind="getFormProps"
      v-if="getBindValues.useSearchForm"
      :submitButtonOptions="{ loading }"
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"
26
      v-bind="getBindValues"
27
      :rowClassName="getRowClassName"
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
43
    SizeType,
44
45
    SorterResult,
    TableCustomRecord,
46
  } from './types/table';
47
  import { PaginationProps } from './types/pagination';
vben authored
48
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';
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
67
68
  import { useEventListener } from '/@/hooks/event/useEventListener';
69
70
  import { basicProps } from './props';
  import { ROW_KEY } from './const';
vben authored
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
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
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
119
120
      const getBindValues = computed(() => {
vben authored
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
126
          hideTitle && !isString(title)
127
128
            ? {}
            : {
vben authored
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
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
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;
      });
195
196
197
198
199
200
201
202
      watch(
        () => unref(getDataSourceRef),
        () => {
          handleSummary();
        },
        { immediate: true }
      );
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 });
      }
220
221
      function handleTableChange(
        pagination: PaginationProps,
222
        // @ts-ignore
223
        filters: Partial<Record<string, string[]>>,
224
        sorter: SorterResult
225
226
      ) {
        const { clearSelectOnPageChange, sortFn } = unref(getMergeProps);
227
228
229
230
        if (clearSelectOnPageChange) {
          clearSelectedRowKeys();
        }
        setPagination(pagination);
231
232
233
234
235
236

        if (sorter && isFunction(sortFn)) {
          const sortInfo = sortFn(sorter);
          fetch({ sortInfo });
          return;
        }
237
238
        fetch();
      }
vben authored
239
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];
249
            useEventListener({
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
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
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
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
303
304
305
        setProps,
        getSize: (): SizeType => {
          return unref(getBindValues).size;
306
307
308
        },
      };
vben authored
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
325
        wrapRef,
326
        tableAction,
327
328
329
330
331
        ...tableAction,
      };
    },
  });
</script>