From 0078559e4b629687ebf974a3f2c50601610a0994 Mon Sep 17 00:00:00 2001 From: xingyu Date: Fri, 4 Aug 2023 20:21:35 +0800 Subject: [PATCH] feat: useWindowSizeFn --- .../Table/src/hooks/useTableScroll.ts | 131 ++++++++++++------ src/hooks/event/useWindowSizeFn.ts | 12 +- src/hooks/web/useContentHeight.ts | 3 +- .../default/content/useContentViewHeight.ts | 3 +- src/views/base/iframe/index.vue | 2 +- 5 files changed, 98 insertions(+), 53 deletions(-) diff --git a/src/components/Table/src/hooks/useTableScroll.ts b/src/components/Table/src/hooks/useTableScroll.ts index 7b089820..0faa123b 100644 --- a/src/components/Table/src/hooks/useTableScroll.ts +++ b/src/components/Table/src/hooks/useTableScroll.ts @@ -2,9 +2,9 @@ import type { ComputedRef, Ref } from 'vue' import { computed, nextTick, ref, unref, watch } from 'vue' import { useDebounceFn } from '@vueuse/core' import type { BasicColumn, BasicTableProps, TableRowSelection } from '../types/table' +import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn' import { getViewportOffset } from '@/utils/domUtils' import { isBoolean } from '@/utils/is' -import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn' import { useModalContext } from '@/components/Modal' import { onMountedOrActivated } from '@/hooks/core/onMountedOrActivated' @@ -55,52 +55,29 @@ export function useTableScroll( let footerEl: HTMLElement | null let bodyEl: HTMLElement | null - async function calcTableHeight() { - const { resizeHeightOffset, pagination, maxHeight, isCanResizeParent, useSearchForm } = 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 - } - + function handleScrollBar(bodyEl: HTMLElement, tableEl: Element) { const hasScrollBarY = bodyEl.scrollHeight > bodyEl.clientHeight const hasScrollBarX = bodyEl.scrollWidth > bodyEl.clientWidth - if (hasScrollBarY) - tableEl.classList.contains('hide-scrollbar-y') && tableEl.classList.remove('hide-scrollbar-y') - else + if (hasScrollBarY) { + tableEl.classList.contains('hide-scrollbar-y') + && tableEl.classList.remove('hide-scrollbar-y') + } + else { !tableEl.classList.contains('hide-scrollbar-y') && tableEl.classList.add('hide-scrollbar-y') + } - if (hasScrollBarX) - tableEl.classList.contains('hide-scrollbar-x') && tableEl.classList.remove('hide-scrollbar-x') - else + if (hasScrollBarX) { + tableEl.classList.contains('hide-scrollbar-x') + && tableEl.classList.remove('hide-scrollbar-x') + } + else { !tableEl.classList.contains('hide-scrollbar-x') && tableEl.classList.add('hide-scrollbar-x') + } + } - bodyEl.style.height = 'unset' - - if (!unref(getCanResize) || !unref(tableData) || tableData.length === 0) - return - - await nextTick() - // Add a delay to get the correct bottomIncludeBody paginationHeight footerHeight headerHeight - - const headEl = tableEl.querySelector('.ant-table-thead ') - - if (!headEl) - return - - // Table height from bottom height-custom offset - let paddingHeight = 32 + function caclPaginationHeight(tableEl: Element): number { + const { pagination } = unref(propsRef) // Pager height let paginationHeight = 2 if (!isBoolean(pagination)) { @@ -117,7 +94,11 @@ export function useTableScroll( else { paginationHeight = -8 } + return paginationHeight + } + function caclFooterHeight(tableEl: Element): number { + const { pagination } = unref(propsRef) let footerHeight = 0 if (!isBoolean(pagination)) { if (!footerEl) { @@ -128,11 +109,21 @@ export function useTableScroll( footerHeight += offsetHeight || 0 } } + return footerHeight + } + function calcHeaderHeight(headEl: Element): number { let headerHeight = 0 if (headEl) headerHeight = (headEl as HTMLElement).offsetHeight + return headerHeight + } + + function calcBottomAndPaddingHeight(tableEl: Element, headEl: Element) { + const { pagination, isCanResizeParent, useSearchForm } = unref(propsRef) + // Table height from bottom height-custom offset + let paddingHeight = 30 let bottomIncludeBody = 0 if (unref(wrapRef) && isCanResizeParent) { const tablePadding = 12 @@ -150,23 +141,75 @@ export function useTableScroll( if (isBoolean(useSearchForm) && !useSearchForm) paddingHeight = 0 - const headerCellHeight = (tableEl.querySelector('.ant-table-title') as HTMLElement)?.offsetHeight ?? 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 + bottomIncludeBody + = wrapHeight - formHeight - headerCellHeight - tablePadding - paginationMargin } else { // Table height from bottom bottomIncludeBody = getViewportOffset(headEl).bottomIncludeBody } - let height = bottomIncludeBody - (resizeHeightOffset || 0) - paddingHeight - paginationHeight - footerHeight - headerHeight + return { + paddingHeight, + bottomIncludeBody, + } + } + + 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' + + if (!unref(getCanResize) || !unref(tableData) || tableData.length === 0) + return + + await nextTick() + // Add a delay to get the correct bottomIncludeBody paginationHeight footerHeight headerHeight + + const headEl = tableEl.querySelector('.ant-table-thead ') + + if (!headEl) + return + + const paginationHeight = caclPaginationHeight(tableEl) + const footerHeight = caclFooterHeight(tableEl) + const headerHeight = calcHeaderHeight(headEl) + const { paddingHeight, bottomIncludeBody } = calcBottomAndPaddingHeight(tableEl, headEl) + + let height + = bottomIncludeBody + - (resizeHeightOffset || 0) + - paddingHeight + - paginationHeight + - footerHeight + - headerHeight height = (height > maxHeight! ? (maxHeight as number) : height) ?? height setHeight(height) bodyEl.style.height = `${height}px` } - useWindowSizeFn(calcTableHeight, 280) + useWindowSizeFn(calcTableHeight, { wait: 280 }) onMountedOrActivated(() => { calcTableHeight() nextTick(() => { diff --git a/src/hooks/event/useWindowSizeFn.ts b/src/hooks/event/useWindowSizeFn.ts index 559d06ac..c83ed71a 100644 --- a/src/hooks/event/useWindowSizeFn.ts +++ b/src/hooks/event/useWindowSizeFn.ts @@ -1,12 +1,14 @@ import { tryOnMounted, tryOnUnmounted, useDebounceFn } from '@vueuse/core' -interface WindowSizeOptions { +interface UseWindowSizeOptions { + wait?: number once?: boolean immediate?: boolean listenerOptions?: AddEventListenerOptions | boolean } -export function useWindowSizeFn(fn: Fn, wait = 150, options?: WindowSizeOptions) { +function useWindowSizeFn(fn: Fn, options: UseWindowSizeOptions = {}) { + const { wait = 150, immediate } = options let handler = () => { fn() } @@ -14,7 +16,7 @@ export function useWindowSizeFn(fn: Fn, wait = 150, options?: WindowSizeOp handler = handleSize const start = () => { - if (options && options.immediate) + if (immediate) handler() window.addEventListener('resize', handler) @@ -31,5 +33,7 @@ export function useWindowSizeFn(fn: Fn, wait = 150, options?: WindowSizeOp tryOnUnmounted(() => { stop() }) - return [start, stop] + return { start, stop } } + +export { useWindowSizeFn, type UseWindowSizeOptions } diff --git a/src/hooks/web/useContentHeight.ts b/src/hooks/web/useContentHeight.ts index 4b946b8c..6213fae8 100644 --- a/src/hooks/web/useContentHeight.ts +++ b/src/hooks/web/useContentHeight.ts @@ -168,8 +168,7 @@ export function useContentHeight( () => { calcContentHeight() }, - 50, - { immediate: true }, + { wait: 50, immediate: true }, ) watch( () => [layoutFooterHeightRef.value], diff --git a/src/layouts/default/content/useContentViewHeight.ts b/src/layouts/default/content/useContentViewHeight.ts index 922c6f2b..629ee367 100644 --- a/src/layouts/default/content/useContentViewHeight.ts +++ b/src/layouts/default/content/useContentViewHeight.ts @@ -26,8 +26,7 @@ export function useContentViewHeight() { () => { contentHeight.value = window.innerHeight }, - 100, - { immediate: true }, + { wait: 100, immediate: true }, ) function setPageHeight(height: number) { diff --git a/src/views/base/iframe/index.vue b/src/views/base/iframe/index.vue index 0eb3e614..19642512 100644 --- a/src/views/base/iframe/index.vue +++ b/src/views/base/iframe/index.vue @@ -18,7 +18,7 @@ const frameRef = ref() const { headerHeightRef } = useLayoutHeight() const { prefixCls } = useDesign('iframe-page') -useWindowSizeFn(calcHeight, 150, { immediate: true }) +useWindowSizeFn(calcHeight, { wait: 150, immediate: true }) const getWrapStyle = computed((): CSSProperties => { return {