feat: useWindowSizeFn

pull/28/head
xingyu 2023-08-04 20:21:35 +08:00
parent bfbc45abf8
commit 0078559e4b
5 changed files with 98 additions and 53 deletions

View File

@ -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(() => {

View File

@ -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<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOptions) {
function useWindowSizeFn<T>(fn: Fn<T>, options: UseWindowSizeOptions = {}) {
const { wait = 150, immediate } = options
let handler = () => {
fn()
}
@ -14,7 +16,7 @@ export function useWindowSizeFn<T>(fn: Fn<T>, 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<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOp
tryOnUnmounted(() => {
stop()
})
return [start, stop]
return { start, stop }
}
export { useWindowSizeFn, type UseWindowSizeOptions }

View File

@ -168,8 +168,7 @@ export function useContentHeight(
() => {
calcContentHeight()
},
50,
{ immediate: true },
{ wait: 50, immediate: true },
)
watch(
() => [layoutFooterHeightRef.value],

View File

@ -26,8 +26,7 @@ export function useContentViewHeight() {
() => {
contentHeight.value = window.innerHeight
},
100,
{ immediate: true },
{ wait: 100, immediate: true },
)
function setPageHeight(height: number) {

View File

@ -18,7 +18,7 @@ const frameRef = ref<HTMLElement>()
const { headerHeightRef } = useLayoutHeight()
const { prefixCls } = useDesign('iframe-page')
useWindowSizeFn(calcHeight, 150, { immediate: true })
useWindowSizeFn(calcHeight, { wait: 150, immediate: true })
const getWrapStyle = computed((): CSSProperties => {
return {