浏览代码

feat: 完善列设置的表格重计算

lanjianrong 5 年之前
父节点
当前提交
87ecba9511

+ 21 - 4
src/components/Table/src/BasicTable.tsx

@@ -4,10 +4,11 @@ import { PERMISSION_SELECT_KEY } from '@/utils/cache/cacheEnum'
 import PermSelect from '@/pages/Customer/Company/components/PermSelect'
 import { TABLE_COLUMNS_MAP, ColumnStateEnum } from '@/utils/cache/cacheEnum'
 import { isNullOrUnDef } from '@/utils/is'
+import type { ColumnsState } from '@ant-design/pro-table'
 import ProTable from '@ant-design/pro-table'
 import { useModel } from 'umi'
 import { getAuthCache, setAuthCache } from '@/utils/auth'
-import React, { useRef, useState, useLayoutEffect } from 'react'
+import React, { useRef, useState, useLayoutEffect, useMemo } from 'react'
 import { useMount } from 'ahooks'
 import { useTableScroll } from './hooks/useTableScroll'
 import type { BasicTableProps } from '@/types/typing'
@@ -30,6 +31,7 @@ const BasicTable: {
   columns,
   onColumnsStateChange,
   onSizeChange,
+  bordered,
   ...resetProps
 }) => {
   const {
@@ -43,9 +45,6 @@ const BasicTable: {
     defaultpermAuthCache = permAuthCache[mainMenuType]
   }
   const tableElRef = useRef<HTMLElement>(null)
-  const { getScrollRef, redoHeight } = useTableScroll(tableElRef, columns)
-
-  console.log('getScrollRef', getScrollRef)
 
   const [state, setState] = useState({
     columnsStateMap: {},
@@ -53,6 +52,21 @@ const BasicTable: {
     dataSource: null
   })
 
+  const columnsRef = useMemo(() => {
+    const columnsKeys = Object.keys(state.columnsStateMap)
+    const filterKey = []
+    columnsKeys.forEach(columnsKey => {
+      const column = state.columnsStateMap[columnsKey]
+      if (!column.show) filterKey.push(columnsKey)
+    })
+
+    return columns?.filter((_, i) => !filterKey.includes(i.toString()))
+  }, [state.columnsStateMap])
+
+  const { getScrollRef, redoHeight } = useTableScroll(tableElRef, columnsRef)
+
+  // console.log('getScrollRef', getScrollRef)
+
   useLayoutEffect(() => {
     if (state.dataSource) {
       redoHeight(state.dataSource)
@@ -88,6 +102,8 @@ const BasicTable: {
   }
 
   const handleOnColumnsChange = (map: Record<string, ColumnsState>) => {
+    console.log('map', map)
+
     setState({ ...state, columnsStateMap: map })
     setAuthCache(TABLE_COLUMNS_MAP, { [ColumnStateEnum[columnStateType]]: map })
   }
@@ -105,6 +121,7 @@ const BasicTable: {
         columnsStateMap={state.columnsStateMap}
         onColumnsStateChange={handleOnColumnsChange}
         scroll={getScrollRef}
+        bordered={isNullOrUnDef(bordered) ? bordered : true}
         onLoad={dataSource => setState({ ...state, dataSource })}
         onSizeChange={handleOnSizeChange}
       />

+ 47 - 50
src/components/Table/src/hooks/useTableScroll.ts

@@ -7,8 +7,6 @@ import { getViewportOffset } from '@/utils/domUtils'
 import { useWindowSizeFn } from '@/hooks/event/useWindomSizeFn'
 import type { DensitySize } from '@ant-design/pro-table/lib/components/ToolBar/DensityIcon'
 
-const MutationObserver =
-  window.MutationObserver || window.webkitMutationObserver || window.MozMutationObserver
 export function useTableScroll(
   tableElRef: RefObject<HTMLElement>,
   columnsRef: ProColumns<any> = [],
@@ -16,10 +14,9 @@ export function useTableScroll(
 ) {
   // let bodyEl: HTMLElement | null
   const [tableHeight, setTableHeight] = useState(null)
+  const [_dataSource, setDataSource] = useState(null)
 
-  function calcTableHeight(dataSource: any[], size: DensitySize) {
-    console.log('windows.resize')
-
+  function calcTableHeight(dataSource: any[], size: DensitySize = 'middle') {
     const tableEl = tableElRef.current?.querySelector('.ant-table-wrapper')
     if (!tableEl) return
 
@@ -50,58 +47,57 @@ export function useTableScroll(
     }
 
     let headerHeight = 0
-    if (size) {
-      switch (size) {
-        case 'large':
-          headerHeight += 55
-          break
-        case 'small':
-          headerHeight += 39
-          break
-
-        default:
-          headerHeight += 47
-          break
-      }
+    if (headEl) {
+      headerHeight = headEl.offsetHeight
     }
-
     const height = bottomIncludeBody - paddingHeight - paginationHeight - headerHeight
 
-    if (height !== tableHeight) setTableHeight(height)
-
-    const mutationObserver = new MutationObserver(() => {
-      if (!dataSource?.length) {
-        // 针对无数据的情况下,特别设置tboody
-        const tbodyEl: HTMLElement = tableElRef.current
-          ?.querySelector('.ant-table-container')
-          ?.querySelector('.ant-table-tbody')
-
-        tbodyEl.style.height = `${height}px`
-        return
-      }
-      const tbodyEl: HTMLElement =
-        tableElRef.current?.querySelector('.ant-table-container')?.children[1]
-      tbodyEl.style.height = `${height}px`
-    })
-    mutationObserver.observe(tableEl, {
-      childList: true, // 子节点的变动(新增、删除或者更改)
-      // attributes: true, // 目标属性的改变
-      subtree: true // 将观察器应用于该节点的所有后代节点
-      // attributeFilter: ['class'] // Array - 观察指定属性
-    })
+    // console.log(
+    //   'bottomIncludeBody',
+    //   bottomIncludeBody,
+    //   'paddingHeight',
+    //   paddingHeight,
+    //   'paginationHeight',
+    //   paginationHeight,
+    //   'headerHeight',
+    //   headerHeight
+    // )
+
+    setTableHeight(dataSource?.length ? height : null)
+    if (!dataSource?.length) {
+      // TODO:针对无数据的情况下,特别设置tboody
+      const tbodyEl: HTMLElement = tableElRef.current
+        ?.querySelector('.ant-table-container')
+        ?.querySelector('.ant-table-tbody')
+      const hasScrollBar =
+        tableElRef.current?.querySelector('.ant-table-container')?.querySelector('table')?.style
+          .width !== '100%'
+
+      const notDataHeight = `calc(100vh - 48px - 48px - 64px - ${headerHeight}px - ${
+        hasScrollBar ? 8 : 0
+      }px)`
+      tbodyEl && (tbodyEl!.style.height = notDataHeight)
+      return
+    }
+    const tbodyEl: HTMLElement =
+      tableElRef.current?.querySelector('.ant-table-container')?.children[1]
+    tbodyEl && (tbodyEl!.style.height = `${height}px`)
   }
 
   function redoHeight(dataSource?: any[], size: DensitySize = 'middle') {
-    calcTableHeight(dataSource, size)
+    if (dataSource) {
+      setDataSource(dataSource)
+    }
+    calcTableHeight(dataSource || _dataSource, size)
   }
-  const { run: debounceRedoHeight } = useDebounceFn(redoHeight, { wait: 300 })
+  const { run: debounceRedoHeight } = useDebounceFn(redoHeight, { wait: 180 })
 
-  // Greater than animation time 280
-  useWindowSizeFn(calcTableHeight, 280)
+  // Greater than animation time 180
+  useWindowSizeFn(() => debounceRedoHeight(), 180)
 
   useUpdateLayoutEffect(() => {
     debounceRedoHeight()
-  }, [selectKeysRef?.length])
+  }, [selectKeysRef, columnsRef])
 
   const getSrollX = useMemo(() => {
     let width = 0
@@ -109,7 +105,7 @@ export function useTableScroll(
       width += 60
     }
 
-    // TODO props ?? 0;
+    // TODO: props ?? 0;
     const NORMAL_WIDTH = 150
 
     const columns = columnsRef.filter(item => !item.defaultHidden)
@@ -129,10 +125,11 @@ export function useTableScroll(
     const tableWidth = tableEl && tableEl?.offsetWidth ? tableEl?.offsetWidth : 0
 
     return tableWidth > width ? '100%' : width
-  }, [selectKeysRef])
+  }, [selectKeysRef, columnsRef])
 
   const getScrollRef = useMemo(() => {
-    return { x: getSrollX, y: tableHeight || null }
+    return { x: getSrollX, y: tableHeight }
   }, [getSrollX, tableHeight])
-  return { getScrollRef, redoHeight }
+
+  return { getScrollRef, redoHeight: debounceRedoHeight }
 }

+ 1 - 1
src/hooks/event/useWindomSizeFn.ts

@@ -12,7 +12,7 @@ export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOp
 
   const start = () => {
     if (options && options.immediate) {
-      handler()
+      fn()
     }
     window.addEventListener('resize', handler)
   }