From a4ee6ba0ca28833cbbb8cf0e675561b10fa4c1af Mon Sep 17 00:00:00 2001 From: Ben Lin <maobin001@msn.com> Date: 星期四, 12 九月 2024 01:23:40 +0800 Subject: [PATCH] 规则维护更新 --- src/components/Table/src/hooks/useTableScroll.ts | 318 ++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 232 insertions(+), 86 deletions(-) diff --git a/src/components/Table/src/hooks/useTableScroll.ts b/src/components/Table/src/hooks/useTableScroll.ts index 3777d6e..10313e9 100644 --- a/src/components/Table/src/hooks/useTableScroll.ts +++ b/src/components/Table/src/hooks/useTableScroll.ts @@ -1,10 +1,19 @@ import type { BasicTableProps, TableRowSelection, BasicColumn } from '../types/table'; import { Ref, ComputedRef, ref, computed, unref, nextTick, watch } from 'vue'; -import { getViewportOffset } from '/@/utils/domUtils'; -import { isBoolean } from '/@/utils/is'; +import { getViewportOffset } from '@/utils/domUtils'; +import { isBoolean } from '@/utils/is'; import { useWindowSizeFn, onMountedOrActivated } from '@vben/hooks'; -import { useModalContext } from '/@/components/Modal'; -import { useDebounceFn } from '@vueuse/core'; +import { useModalContext } from '@/components/Modal'; +import { useDebounceFn, promiseTimeout } from '@vueuse/core'; + +import { + footerHeight as layoutFooterHeight, + layoutMultipleHeadePlaceholderTime, +} from '@/settings/designSetting'; + +import { useRootSetting } from '@/hooks/setting/useRootSetting'; + +const { getShowFooter, getFullContent } = useRootSetting(); export function useTableScroll( propsRef: ComputedRef<BasicTableProps>, @@ -27,8 +36,20 @@ }); watch( - () => [unref(getCanResize), unref(getDataSourceRef)?.length], + () => [unref(getCanResize), unref(getDataSourceRef)?.length, unref(getShowFooter)], () => { + debounceRedoHeight(); + }, + { + flush: 'post', + }, + ); + + watch( + () => [unref(getFullContent)], + async () => { + // 绛夊緟鍔ㄧ敾缁撴潫鍚�200姣 + await promiseTimeout(layoutMultipleHeadePlaceholderTime * 1000 + 200); debounceRedoHeight(); }, { @@ -53,22 +74,13 @@ let footerEl: HTMLElement | null; let bodyEl: HTMLElement | null; - async function calcTableHeight() { - const { resizeHeightOffset, pagination, maxHeight, isCanResizeParent, useSearchForm } = - unref(propsRef); - const tableData = unref(getDataSourceRef); + /** + * table wrapper padding 鐨勯珮搴� + * @description 鏉ヨ嚜浜� .vben-basic-table .ant-table-wrapper + */ + const tableWrapperPadding = 6; - const table = unref(tableElRef); - if (!table) return; - - const tableEl: Element = table.$el; - if (!tableEl) return; - - if (!bodyEl) { - bodyEl = tableEl.querySelector('.ant-table-body'); - if (!bodyEl) return; - } - + function handleScrollBar(bodyEl: HTMLElement, tableEl: Element) { const hasScrollBarY = bodyEl.scrollHeight > bodyEl.clientHeight; const hasScrollBarX = bodyEl.scrollWidth > bodyEl.clientWidth; @@ -85,6 +97,180 @@ } else { !tableEl.classList.contains('hide-scrollbar-x') && tableEl.classList.add('hide-scrollbar-x'); } + } + + /** + * 璁$畻鍒嗛〉鍣ㄩ珮搴� + * @param tableEl table element + * @returns number + */ + function caclPaginationHeight(tableEl: Element): number { + const { pagination } = unref(propsRef); + + let paginationHeight = 0; + if (!isBoolean(pagination)) { + // 浠� Dom 鑾峰彇 + if (!paginationEl) { + paginationEl = tableEl.querySelector('.ant-pagination') as HTMLElement; + } + if (paginationEl) { + // 鍒嗛〉 margin-top + const paginationElMarginTop = + parseInt(getComputedStyle(paginationEl)?.marginTop) || 10 + 24; + // 鍒嗛〉楂樺害 + const offsetHeight = paginationEl.offsetHeight; + paginationHeight = offsetHeight + paginationElMarginTop; + } else { + // 鎵句笉鍒板垎椤电粍浠讹紝缂虹渷缁欎簣榛樿鍒嗛〉 margin-top + 楂樺害 + paginationHeight = 10 + 24; + } + } else { + // 涓嶆樉绀哄垎椤碉紝pagination 涓� false 鐨勬椂鍊� + paginationHeight = 0; + } + return paginationHeight; + } + + function caclFooterHeight(tableEl: Element): number { + const { pagination } = unref(propsRef); + let footerHeight = 0; + if (!isBoolean(pagination)) { + if (!footerEl) { + footerEl = tableEl.querySelector('.ant-table-footer') as HTMLElement; + } else { + const offsetHeight = footerEl.offsetHeight; + footerHeight += offsetHeight || 0; + } + } + return footerHeight; + } + + function calcHeaderHeight(headEl: Element): number { + let headerHeight = 0; + if (headEl) { + headerHeight = (headEl as HTMLElement).offsetHeight; + } + return headerHeight; + } + + /** + * 璁$畻浠庤〃澶翠竴鐩村埌body搴曢儴鐨勬�婚珮搴� + * @param tableEl table element + * @param headEl table 椤靛ご element + * @returns number + */ + function calcBottomAndPaddingHeight(tableEl: Element, headEl: Element) { + const { isCanResizeParent } = unref(propsRef); + let bottomIncludeBody = 0; + if (unref(wrapRef) && isCanResizeParent) { + // 缁ф壙鐖跺厓绱犻珮搴� + const wrapHeight = unref(wrapRef)?.offsetHeight ?? 0; + + let formHeight = unref(formRef)?.$el.offsetHeight ?? 0; + if (formHeight) { + // 鏉ヨ嚜浜� .vben-basic-table-form-container .ant-form 浠ュ強 .vben-basic-table-form-container + formHeight += 16 + 16 * 2; + } + + bottomIncludeBody = wrapHeight - tableWrapperPadding - formHeight; + } else { + // 缂虹渷 wrapRef 鎯呭喌涓� + bottomIncludeBody = getViewportOffset(headEl).bottomIncludeBody; + } + + return bottomIncludeBody; + } + + /** + * 璁$畻 table 鍦� modal 鍐� modal 鎵�鍗犵敤鐨勯珮搴� + * @param tableEl table element + * @returns number + */ + function calcModalHeight(tableEl: Element) { + // 鎵句竴涓� table 鏄惁鍦� modal 鍐咃紝鑾峰緱 modal銆亀rap銆乫ooter锛屽苟鑰冭檻 fullscreen 鐨勬儏鍐� + let modalEl: Nullable<HTMLElement> = null; + let modalWrapEl: Nullable<HTMLElement> = null; + let modalFooterEl: Nullable<HTMLElement> = null; + let modalElIterator: HTMLElement = tableEl.parentElement!; + let modalIsFullscreen = false; + while (modalElIterator !== document.body) { + if (!modalElIterator) break; + if (modalElIterator.classList.contains('ant-modal')) { + modalEl = modalElIterator; + modalWrapEl = modalEl.parentElement; + modalFooterEl = modalElIterator.querySelector('.ant-modal-content>.ant-modal-footer'); + modalIsFullscreen = modalWrapEl?.classList.contains('fullscreen-modal') ?? false; + break; + } + modalElIterator = modalElIterator.parentElement!; + } + + if (modalEl) { + // table 鍦� modal 鍐� + + // modal top + const { top: modalTop = 0 } = modalEl ? getViewportOffset(modalEl) : {}; + + // 鏉ヨ嚜浜� .ant-modal锛岄潪鍏ㄥ睆涓� 24锛屽叏灞忎负 0 + const modalBottom = modalIsFullscreen ? 0 : 24; + + // modal footer 楂樺害 + const modalFooterHeight = modalFooterEl?.offsetHeight ?? 0; + + // modal footer 杈硅窛锛屾潵鑷簬 .ant-modal .ant-modal-footer + const modalFooterMarginTop = modalFooterEl + ? modalIsFullscreen + ? 0 + : parseInt(getComputedStyle(modalFooterEl).marginTop) + : 0; + + // 鏉ヨ嚜浜� .ant-modal .ant-modal-body > .scrollbar + const modalScrollBarHeight = 14; + + return ( + (modalTop > modalBottom ? modalTop : modalBottom) + + modalFooterHeight + + modalFooterMarginTop + + modalScrollBarHeight + ); + } + + // table 涓嶄綇 modal 鍐� + return 0; + } + + /** + * 鏍规嵁鏍峰紡杩斿洖涓�浜涢棿璺濋珮搴� + * @returns number + */ + function getMarginPaddingHeight() { + const { isCanResizeParent } = unref(propsRef); + + if (unref(wrapRef) && isCanResizeParent) { + // 缁ф壙鐖跺厓绱犻珮搴� + return tableWrapperPadding; + } + return ( + tableWrapperPadding + 16 // 鏉ヨ嚜浜� .vben-basic-table-form-container 鎴栨槸 .p-4 + ); + } + + async function calcTableHeight() { + const { resizeHeightOffset, maxHeight } = unref(propsRef); + const tableData = unref(getDataSourceRef); + + const table = unref(tableElRef); + if (!table) return; + + const tableEl: Element = table.$el; + if (!tableEl) return; + + if (!bodyEl) { + bodyEl = tableEl.querySelector('.ant-table-body'); + if (!bodyEl) return; + } + + handleScrollBar(bodyEl, tableEl); bodyEl!.style.height = 'unset'; @@ -97,74 +283,32 @@ if (!headEl) return; - // Table height from bottom height-custom offset - let paddingHeight = 32; - // Pager height - let paginationHeight = 2; - if (!isBoolean(pagination)) { - paginationEl = tableEl.querySelector('.ant-pagination') as HTMLElement; - if (paginationEl) { - const offsetHeight = paginationEl.offsetHeight; - paginationHeight += offsetHeight || 0; - } else { - // TODO First fix 24 - paginationHeight += 24; - } - } else { - paginationHeight = -8; - } + const paginationHeight = caclPaginationHeight(tableEl); + const footerHeight = caclFooterHeight(tableEl); + const headerHeight = calcHeaderHeight(headEl); + const bottomIncludeBody = calcBottomAndPaddingHeight(tableEl, headEl); - let footerHeight = 0; - if (!isBoolean(pagination)) { - if (!footerEl) { - footerEl = tableEl.querySelector('.ant-table-footer') as HTMLElement; - } else { - const offsetHeight = footerEl.offsetHeight; - footerHeight += offsetHeight || 0; - } - } + const modalHeight = calcModalHeight(tableEl); - let headerHeight = 0; - if (headEl) { - headerHeight = (headEl as HTMLElement).offsetHeight; - } + const marginPaddingHeight = getMarginPaddingHeight(); - 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 = + // Math.floor 瀹佹効灏�1px锛屼篃涓嶆孩鍑� + let height = Math.floor( bottomIncludeBody - - (resizeHeightOffset || 0) - - paddingHeight - - paginationHeight - - footerHeight - - headerHeight; + (resizeHeightOffset || 0) - + paginationHeight - + footerHeight - + headerHeight - + // 寮圭獥锛堝鏋滄湁锛夌浉鍏抽珮搴� + modalHeight - + // 椤甸潰 footer 楂樺害锛堥潪寮圭獥鐨勬椂鍊欙級 + (getShowFooter.value && modalHeight <= 0 ? layoutFooterHeight : 0) - + // 鏍峰紡闂磋窛楂樺害 + marginPaddingHeight - + // 棰勭暀闈炴暣鏁伴珮搴︽孩鍑猴紙濡傚疄闄呴珮搴︿负100.5锛宱ffsetHeight 鐨勫�间负101锛� + 1, + ); + height = (height > maxHeight! ? (maxHeight as number) : height) ?? height; setHeight(height); @@ -191,7 +335,9 @@ columns.forEach((item) => { width += Number.parseFloat(item.width as string) || 0; }); - const unsetWidthColumns = columns.filter((item) => !Reflect.has(item, 'width')); + const unsetWidthColumns = columns.filter( + (item) => !Reflect.has(item, 'width') && item.ifShow !== false, + ); const len = unsetWidthColumns.length; if (len !== 0) { @@ -211,7 +357,7 @@ y: canResize ? tableHeight : null, scrollToFirstRowOnChange: false, ...scroll, - }; + } as BasicTableProps['scroll']; }); return { getScrollRef, redoHeight }; -- Gitblit v1.9.3