feat: useWindowSizeFn
parent
bfbc45abf8
commit
0078559e4b
|
@ -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(() => {
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -168,8 +168,7 @@ export function useContentHeight(
|
|||
() => {
|
||||
calcContentHeight()
|
||||
},
|
||||
50,
|
||||
{ immediate: true },
|
||||
{ wait: 50, immediate: true },
|
||||
)
|
||||
watch(
|
||||
() => [layoutFooterHeightRef.value],
|
||||
|
|
|
@ -26,8 +26,7 @@ export function useContentViewHeight() {
|
|||
() => {
|
||||
contentHeight.value = window.innerHeight
|
||||
},
|
||||
100,
|
||||
{ immediate: true },
|
||||
{ wait: 100, immediate: true },
|
||||
)
|
||||
|
||||
function setPageHeight(height: number) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue