Browse Source

feat: 添加table继承父元素高度的功能 (#1523)

在保证了原有的高度计算上,额外新增继承父级高度, 只需设置isCanResizeParent:true
lzdjack 3 years ago
parent
commit
dd158a17fe

+ 7 - 1
src/components/Table/src/BasicTable.vue

@@ -1,6 +1,7 @@
 <template>
   <div ref="wrapRef" :class="getWrapperClass">
     <BasicForm
+      ref="formRef"
       submitOnReset
       v-bind="getFormProps"
       v-if="getBindValues.useSearchForm"
@@ -25,7 +26,7 @@
         <slot :name="item" v-bind="data || {}"></slot>
       </template>
 
-      <template #[`header-${column.dataIndex}`] v-for="column in columns" :key="column.dataIndex">
+      <template #[`header-${column.dataIndex}`] v-for="(column, index) in columns" :key="index">
         <HeaderCell :column="column" />
       </template>
     </Table>
@@ -97,6 +98,7 @@
       const tableData = ref<Recordable[]>([]);
 
       const wrapRef = ref(null);
+      const formRef = ref(null);
       const innerPropsRef = ref<Partial<BasicTableProps>>();
 
       const { prefixCls } = useDesign('basic-table');
@@ -185,6 +187,8 @@
         getColumnsRef,
         getRowSelectionRef,
         getDataSourceRef,
+        wrapRef,
+        formRef,
       );
 
       const { scrollTo } = useTableScrollTo(tableElRef, getDataSourceRef);
@@ -318,6 +322,7 @@
       emit('register', tableAction, formActions);
 
       return {
+        formRef,
         tableElRef,
         getBindValues,
         getLoading,
@@ -352,6 +357,7 @@
 
   .@{prefix-cls} {
     max-width: 100%;
+    height: 100%;
 
     &-row__striped {
       td {

+ 41 - 10
src/components/Table/src/hooks/useTableScroll.ts

@@ -1,5 +1,5 @@
 import type { BasicTableProps, TableRowSelection, BasicColumn } from '../types/table';
-import type { Ref, ComputedRef } from 'vue';
+import { Ref, ComputedRef, ref } from 'vue';
 import { computed, unref, nextTick, watch } from 'vue';
 import { getViewportOffset } from '/@/utils/domUtils';
 import { isBoolean } from '/@/utils/is';
@@ -14,7 +14,10 @@ export function useTableScroll(
   columnsRef: ComputedRef<BasicColumn[]>,
   rowSelectionRef: ComputedRef<TableRowSelection | null>,
   getDataSourceRef: ComputedRef<Recordable[]>,
+  wrapRef: Ref<HTMLElement | null>,
+  formRef: Ref<ComponentRef>,
 ) {
+  const tableHeightRef: Ref<Nullable<number | string>> = ref(167);
   const modalFn = useModalContext();
 
   // Greater than animation time 280
@@ -41,7 +44,8 @@ export function useTableScroll(
     });
   }
 
-  function setHeight() {
+  function setHeight(height: number) {
+    tableHeightRef.value = height;
     //  Solve the problem of modal adaptive height calculation when the form is placed in the modal
     modalFn?.redoModalHeight?.();
   }
@@ -52,7 +56,8 @@ export function useTableScroll(
   let bodyEl: HTMLElement | null;
 
   async function calcTableHeight() {
-    const { resizeHeightOffset, pagination, maxHeight } = unref(propsRef);
+    const { resizeHeightOffset, pagination, maxHeight, isCanResizeParent, useSearchForm } =
+      unref(propsRef);
     const tableData = unref(getDataSourceRef);
 
     const table = unref(tableElRef);
@@ -94,11 +99,8 @@ export function useTableScroll(
 
     if (!headEl) return;
 
-    // Table height from bottom
-    const { bottomIncludeBody } = getViewportOffset(headEl);
     // Table height from bottom height-custom offset
-
-    const paddingHeight = 32;
+    let paddingHeight = 32;
     // Pager height
     let paginationHeight = 2;
     if (!isBoolean(pagination)) {
@@ -129,6 +131,35 @@ export function useTableScroll(
       headerHeight = (headEl as HTMLElement).offsetHeight;
     }
 
+    let bottomIncludeBody = 0;
+    if (unref(wrapRef) && isCanResizeParent) {
+      const tablePadding = 12;
+      const formMargin = 16;
+      let paginationMargin = 10;
+      const wrapHeight = unref(wrapRef)?.offsetHeight ?? 0;
+
+      let formHeight = unref(formRef)?.$el.offsetHeight ?? 0;
+      if (formHeight) {
+        formHeight += formMargin;
+      }
+      if (isBoolean(pagination) && !pagination) {
+        paginationMargin = 0;
+      }
+      if (isBoolean(useSearchForm) && !useSearchForm) {
+        paddingHeight = 0;
+      }
+
+      const headerCellHeight =
+        (tableEl.querySelector('.ant-table-title') as HTMLElement)?.offsetHeight ?? 0;
+
+      console.log(wrapHeight - formHeight - headerCellHeight - tablePadding - paginationMargin);
+      bottomIncludeBody =
+        wrapHeight - formHeight - headerCellHeight - tablePadding - paginationMargin;
+    } else {
+      // Table height from bottom
+      bottomIncludeBody = getViewportOffset(headEl).bottomIncludeBody;
+    }
+
     let height =
       bottomIncludeBody -
       (resizeHeightOffset || 0) -
@@ -136,9 +167,8 @@ export function useTableScroll(
       paginationHeight -
       footerHeight -
       headerHeight;
-
     height = (height > maxHeight! ? (maxHeight as number) : height) ?? height;
-    setHeight();
+    setHeight(height);
 
     bodyEl!.style.height = `${height}px`;
   }
@@ -176,10 +206,11 @@ export function useTableScroll(
   });
 
   const getScrollRef = computed(() => {
+    const tableHeight = unref(tableHeightRef);
     const { canResize, scroll } = unref(propsRef);
     return {
       x: unref(getScrollX),
-      y: canResize ? '100%' : null,
+      y: canResize ? tableHeight : null,
       scrollToFirstRowOnChange: false,
       ...scroll,
     };

+ 1 - 0
src/components/Table/src/props.ts

@@ -97,6 +97,7 @@ export const basicProps = {
     default: null,
   },
   ellipsis: { type: Boolean, default: true },
+  isCanResizeParent: { type: Boolean, default: false },
   canResize: { type: Boolean, default: true },
   clearSelectOnPageChange: propTypes.bool,
   resizeHeightOffset: propTypes.number.def(0),

+ 2 - 0
src/components/Table/src/types/table.ts

@@ -191,6 +191,8 @@ export interface BasicTableProps<T = any> {
   actionColumn?: BasicColumn;
   // 文本超过宽度是否显示。。。
   ellipsis?: boolean;
+  // 是否继承父级高度(父级高度-表单高度-padding高度)
+  isCanResizeParent?: boolean;
   // 是否可以自适应高度
   canResize?: boolean;
   // 自适应高度偏移, 计算结果-偏移量

+ 1 - 0
src/locales/lang/en/routes/demo.ts

@@ -195,5 +195,6 @@ export default {
     editCellTable: 'Editable cell',
     editRowTable: 'Editable row',
     authColumn: 'Auth column',
+    resizeParentHeightTable: 'resizeParentHeightTable',
   },
 };

+ 1 - 0
src/locales/lang/zh-CN/routes/demo.ts

@@ -186,5 +186,6 @@ export default {
     editCellTable: '可编辑单元格',
     editRowTable: '可编辑行',
     authColumn: '权限列',
+    resizeParentHeightTable: '继承父元素高度',
   },
 };

+ 8 - 0
src/router/routes/modules/demo/comp.ts

@@ -239,6 +239,14 @@ const comp: AppRouteModule = {
             title: t('routes.demo.table.authColumn'),
           },
         },
+        {
+          path: 'resizeParentHeightTable',
+          name: 'ResizeParentHeightTable',
+          component: () => import('/@/views/demo/table/ResizeParentHeightTable.vue'),
+          meta: {
+            title: t('routes.demo.table.resizeParentHeightTable'),
+          },
+        },
       ],
     },
     {

+ 79 - 0
src/views/demo/table/ResizeParentHeightTable.vue

@@ -0,0 +1,79 @@
+<template>
+  <div class="h-full flex p-4">
+    <div class="flex flex-col pr-4 w-1/2">
+      <div class="flex-1">
+        <BasicTable @register="registerTable" />
+      </div>
+      <div class="h-4"></div>
+      <div class="flex-1">
+        <BasicTable @register="registerTable" />
+      </div>
+    </div>
+    <div class="flex-1 flex flex-col w-1/2 h-full">
+      <div class="h-1/3 mb-4">
+        <BasicTable @register="registerTable" />
+      </div>
+      <div class="h-1/3 mb-4">
+        <BasicTable @register="registerTable2" />
+      </div>
+      <div class="h-1/3">
+        <BasicTable @register="registerTable1" />
+      </div>
+    </div>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicTable, useTable } from '/@/components/Table';
+  import { getBasicColumns, getFormConfig } from './tableData';
+
+  import { demoListApi } from '/@/api/demo/table';
+
+  export default defineComponent({
+    components: { BasicTable },
+    setup(_) {
+      const [registerTable] = useTable({
+        api: demoListApi,
+        columns: getBasicColumns(),
+        useSearchForm: false,
+        formConfig: getFormConfig(),
+        showTableSetting: false,
+        tableSetting: { fullScreen: true },
+        showIndexColumn: false,
+        isCanResizeParent: true,
+        rowKey: 'id',
+      });
+
+      const [registerTable1] = useTable({
+        api: demoListApi,
+        columns: getBasicColumns(),
+        formConfig: getFormConfig(),
+        showTableSetting: false,
+        tableSetting: { fullScreen: true },
+        showIndexColumn: false,
+        isCanResizeParent: true,
+        useSearchForm: false,
+        rowKey: 'id',
+      });
+
+      const [registerTable2] = useTable({
+        api: demoListApi,
+        columns: getBasicColumns(),
+        formConfig: getFormConfig(),
+        showTableSetting: false,
+        tableSetting: { fullScreen: true },
+        showIndexColumn: false,
+        isCanResizeParent: true,
+        useSearchForm: false,
+        pagination: false,
+        rowKey: 'id',
+      });
+
+      return {
+        registerTable,
+        registerTable1,
+        registerTable2,
+      };
+    },
+  });
+</script>