perf(modal): optimize table embedding height calculation problem
| | |
| | | |
| | | - 表单代码优化重构 |
| | | |
| | | ### ⚡ Performance Improvements |
| | | |
| | | - Modal slot 可以覆盖 |
| | | - 优化表格嵌入高度计算问题 |
| | | |
| | | ### 🎫 Chores |
| | | |
| | | - 添加部分注释 |
| | |
| | | {...{ ...attrs, ...props, ...unref(getProps) }} |
| | | > |
| | | {{ |
| | | footer: () => renderFooter(), |
| | | closeIcon: () => renderClose(), |
| | | title: () => renderTitle(), |
| | | ...extendSlots(slots, ['default']), |
| | | default: () => renderContent(), |
| | | closeIcon: () => renderClose(), |
| | | footer: () => renderFooter(), |
| | | title: () => renderTitle(), |
| | | }} |
| | | </Modal> |
| | | ); |
| | |
| | | import { Spin } from 'ant-design-vue'; |
| | | |
| | | import { useWindowSizeFn } from '/@/hooks/event/useWindowSize'; |
| | | import { useTimeout } from '/@/hooks/core/useTimeout'; |
| | | // import { useTimeout } from '/@/hooks/core/useTimeout'; |
| | | |
| | | import { getSlot } from '/@/utils/helper/tsxHelper'; |
| | | import { useElResize } from '/@/hooks/event/useElResize'; |
| | | import { provideModal } from './provideModal'; |
| | | |
| | | export default defineComponent({ |
| | | name: 'ModalWrapper', |
| | | props: { |
| | |
| | | const wrapperRef = ref<HTMLElement | null>(null); |
| | | const spinRef = ref<any>(null); |
| | | const realHeightRef = ref(0); |
| | | // 重试次数 |
| | | // let tryCount = 0; |
| | | let stopElResizeFn: Fn = () => {}; |
| | | |
| | | provideModal(setModalHeight); |
| | | |
| | | const wrapStyle = computed(() => { |
| | | return { |
| | |
| | | overflow: 'auto', |
| | | }; |
| | | }); |
| | | |
| | | // 重试次数 |
| | | let tryCount = 0; |
| | | let stopElResizeFn: Fn = () => {}; |
| | | |
| | | watchEffect(() => { |
| | | setModalHeight(); |
| | |
| | | } |
| | | await nextTick(); |
| | | const spinEl = unref(spinRef); |
| | | if (!spinEl) { |
| | | useTimeout(() => { |
| | | // retry |
| | | if (tryCount < 3) { |
| | | setModalHeight(); |
| | | } |
| | | tryCount++; |
| | | }, 10); |
| | | return; |
| | | } |
| | | tryCount = 0; |
| | | // if (!spinEl) { |
| | | // useTimeout(() => { |
| | | // // retry |
| | | // if (tryCount < 3) { |
| | | // setModalHeight(); |
| | | // } |
| | | // tryCount++; |
| | | // }, 10); |
| | | // return; |
| | | // } |
| | | // tryCount = 0; |
| | | |
| | | const spinContainerEl = spinEl.$el.querySelector('.ant-spin-container') as HTMLElement; |
| | | if (!spinContainerEl) return; |
New file |
| | |
| | | import { provide, inject } from 'vue'; |
| | | |
| | | const key = Symbol('basic-modal'); |
| | | |
| | | export function provideModal(redoHeight: Fn) { |
| | | provide(key, redoHeight); |
| | | } |
| | | |
| | | export function injectModal(): Fn { |
| | | return inject(key) as Fn; |
| | | } |
| | |
| | | import { useTimeout } from '/@/hooks/core/useTimeout'; |
| | | import { useWindowSizeFn } from '/@/hooks/event/useWindowSize'; |
| | | import { useProps } from './useProps'; |
| | | import { injectModal } from '/@/components/Modal/src/provideModal'; |
| | | |
| | | export function useTableScroll(refProps: ComputedRef<BasicTableProps>, tableElRef: Ref<any>) { |
| | | const { propsRef } = useProps(refProps); |
| | | |
| | | const tableHeightRef: Ref<number | null> = ref(null); |
| | | |
| | | const redoModalHeight = injectModal(); |
| | | |
| | | watch( |
| | | () => unref(propsRef).canResize, |
| | |
| | | redoHeight(); |
| | | } |
| | | ); |
| | | |
| | | function redoHeight() { |
| | | const { canResize } = unref(propsRef); |
| | | |
| | | if (!canResize) { |
| | | return; |
| | | } |
| | | if (!canResize) return; |
| | | calcTableHeight(); |
| | | } |
| | | |
| | | async function calcTableHeight(cb?: () => void) { |
| | | const { canResize, resizeHeightOffset, pagination, maxHeight } = unref(propsRef); |
| | | if (!canResize) { |
| | | return; |
| | | } |
| | | if (!canResize) return; |
| | | |
| | | await nextTick(); |
| | | const table = unref(tableElRef) as any; |
| | | if (!table) return; |
| | | |
| | | if (!table) { |
| | | return; |
| | | } |
| | | const tableEl: Element = table.$el; |
| | | if (!tableEl) { |
| | | return; |
| | | } |
| | | if (!tableEl) return; |
| | | |
| | | const el: HTMLElement | null = tableEl.querySelector('.ant-table-thead '); |
| | | // const layoutMain: Element | null = document.querySelector('.default-layout__main '); |
| | | if (!el) { |
| | | return; |
| | | } |
| | | if (!el) return; |
| | | |
| | | // 表格距离底部高度 |
| | | const { bottomIncludeBody } = getViewportOffset(el); |
| | | // 表格高度+距离底部高度-自定义偏移量 |
| | |
| | | tableHeightRef.value = |
| | | tableHeightRef.value! > maxHeight! ? (maxHeight as number) : tableHeightRef.value; |
| | | cb && cb(); |
| | | // 解决表格放modal内的时候,modal自适应高度计算问题 |
| | | redoModalHeight && redoModalHeight(); |
| | | }, 0); |
| | | } |
| | | |