Commit 53867a846154d9a3529f50d20d92ce5fdb41986f
1 parent
1418dc6a
fix(table): ensure that the table height is correct when the data is empty
Showing
4 changed files
with
98 additions
and
94 deletions
CHANGELOG.zh_CN.md
src/components/Page/src/PageWrapper.vue
... | ... | @@ -66,7 +66,7 @@ |
66 | 66 | const headerRef = ref<ComponentRef>(null); |
67 | 67 | const footerRef = ref<ComponentRef>(null); |
68 | 68 | const footerHeight = ref(0); |
69 | - const { prefixCls } = useDesign('page-wrapper'); | |
69 | + const { prefixCls, prefixVar } = useDesign('page-wrapper'); | |
70 | 70 | const { contentHeight, setPageHeight, pageHeight } = usePageContext(); |
71 | 71 | |
72 | 72 | const getClass = computed(() => { |
... | ... | @@ -110,40 +110,39 @@ |
110 | 110 | } |
111 | 111 | nextTick(() => { |
112 | 112 | //fix:in contentHeight mode: delay getting footer and header dom element to get the correct height |
113 | - setTimeout(() => { | |
114 | - const footer = unref(footerRef); | |
115 | - const header = unref(headerRef); | |
116 | - footerHeight.value = 0; | |
117 | - const footerEl = footer?.$el; | |
113 | + const footer = unref(footerRef); | |
114 | + const header = unref(headerRef); | |
115 | + footerHeight.value = 0; | |
116 | + const footerEl = footer?.$el; | |
118 | 117 | |
119 | - if (footerEl) { | |
120 | - footerHeight.value += footerEl?.offsetHeight ?? 0; | |
121 | - } | |
122 | - let headerHeight = 0; | |
123 | - const headerEl = header?.$el; | |
124 | - if (headerEl) { | |
125 | - headerHeight += headerEl?.offsetHeight ?? 0; | |
126 | - } | |
127 | - //fix:subtract content's marginTop and marginBottom value | |
128 | - let subtractHeight = 0; | |
129 | - const attributes = getComputedStyle( | |
130 | - document.querySelectorAll('.vben-page-wrapper-content')[0] | |
131 | - ); | |
132 | - if (attributes.marginBottom) { | |
133 | - const contentMarginBottom = Number(attributes.marginBottom.replace(/[^\d]/g, '')); | |
134 | - subtractHeight += contentMarginBottom; | |
135 | - } | |
136 | - if (attributes.marginTop) { | |
137 | - const contentMarginTop = Number(attributes.marginTop.replace(/[^\d]/g, '')); | |
138 | - subtractHeight += contentMarginTop; | |
139 | - } | |
140 | - setPageHeight?.( | |
141 | - unref(contentHeight) - unref(footerHeight) - headerHeight - subtractHeight | |
142 | - ); | |
143 | - }, 400); | |
118 | + if (footerEl) { | |
119 | + footerHeight.value += footerEl?.offsetHeight ?? 0; | |
120 | + } | |
121 | + let headerHeight = 0; | |
122 | + const headerEl = header?.$el; | |
123 | + if (headerEl) { | |
124 | + headerHeight += headerEl?.offsetHeight ?? 0; | |
125 | + } | |
126 | + // fix:subtract content's marginTop and marginBottom value | |
127 | + let subtractHeight = 0; | |
128 | + const { marginBottom, marginTop } = getComputedStyle( | |
129 | + document.querySelectorAll(`.${prefixVar}-page-wrapper-content`)?.[0] | |
130 | + ); | |
131 | + if (marginBottom) { | |
132 | + const contentMarginBottom = Number(marginBottom.replace(/[^\d]/g, '')); | |
133 | + subtractHeight += contentMarginBottom; | |
134 | + } | |
135 | + if (marginTop) { | |
136 | + const contentMarginTop = Number(marginTop.replace(/[^\d]/g, '')); | |
137 | + subtractHeight += contentMarginTop; | |
138 | + } | |
139 | + setPageHeight?.( | |
140 | + unref(contentHeight) - unref(footerHeight) - headerHeight - subtractHeight | |
141 | + ); | |
144 | 142 | }); |
145 | 143 | }, |
146 | 144 | { |
145 | + flush: 'post', | |
147 | 146 | immediate: true, |
148 | 147 | } |
149 | 148 | ); |
... | ... | @@ -171,6 +170,7 @@ |
171 | 170 | .@{prefix-cls}-content { |
172 | 171 | margin: 16px 16px 0 16px; |
173 | 172 | } |
173 | + | |
174 | 174 | .ant-page-header { |
175 | 175 | &:empty { |
176 | 176 | padding: 0; | ... | ... |
src/components/Table/src/BasicTable.vue
src/components/Table/src/hooks/useTableScroll.ts
... | ... | @@ -14,14 +14,15 @@ export function useTableScroll( |
14 | 14 | propsRef: ComputedRef<BasicTableProps>, |
15 | 15 | tableElRef: Ref<ComponentRef>, |
16 | 16 | columnsRef: ComputedRef<BasicColumn[]>, |
17 | - rowSelectionRef: ComputedRef<TableRowSelection<any> | null> | |
17 | + rowSelectionRef: ComputedRef<TableRowSelection<any> | null>, | |
18 | + getDataSourceRef: ComputedRef<Recordable[]> | |
18 | 19 | ) { |
19 | 20 | const tableHeightRef: Ref<Nullable<number>> = ref(null); |
20 | 21 | |
21 | 22 | const modalFn = useModalContext(); |
22 | 23 | |
23 | - // const [debounceCalcTableHeight] = useDebounce(calcTableHeight, 80); | |
24 | - const [debounceRedoHeight] = useDebounce(redoHeight, 250); | |
24 | + //320 Greater than animation time 280 | |
25 | + const [debounceRedoHeight] = useDebounce(redoHeight, 300); | |
25 | 26 | |
26 | 27 | const getCanResize = computed(() => { |
27 | 28 | const { canResize, scroll } = unref(propsRef); |
... | ... | @@ -34,6 +35,7 @@ export function useTableScroll( |
34 | 35 | debounceRedoHeight(); |
35 | 36 | }, |
36 | 37 | { |
38 | + flush: 'post', | |
37 | 39 | immediate: true, |
38 | 40 | } |
39 | 41 | ); |
... | ... | @@ -59,77 +61,77 @@ export function useTableScroll( |
59 | 61 | |
60 | 62 | async function calcTableHeight() { |
61 | 63 | const { resizeHeightOffset, pagination, maxHeight } = unref(propsRef); |
62 | - if (!unref(getCanResize)) return; | |
64 | + const tableData = unref(getDataSourceRef); | |
65 | + | |
66 | + if (!unref(getCanResize) || tableData.length === 0) return; | |
63 | 67 | |
64 | 68 | await nextTick(); |
65 | 69 | //Add a delay to get the correct bottomIncludeBody paginationHeight footerHeight headerHeight |
66 | - setTimeout(() => { | |
67 | - const table = unref(tableElRef); | |
68 | - if (!table) return; | |
69 | - | |
70 | - const tableEl: Element = table.$el; | |
71 | - if (!tableEl) return; | |
72 | - | |
73 | - const headEl = tableEl.querySelector('.ant-table-thead '); | |
74 | - | |
75 | - if (!headEl) return; | |
76 | - | |
77 | - // Table height from bottom | |
78 | - const { bottomIncludeBody } = getViewportOffset(headEl); | |
79 | - // Table height from bottom height-custom offset | |
80 | - | |
81 | - const paddingHeight = 32; | |
82 | - const borderHeight = 0; | |
83 | - // Pager height | |
84 | - let paginationHeight = 2; | |
85 | - if (!isBoolean(pagination)) { | |
86 | - if (!paginationEl) { | |
87 | - paginationEl = tableEl.querySelector('.ant-pagination') as HTMLElement; | |
88 | - } | |
89 | - if (paginationEl) { | |
90 | - const offsetHeight = paginationEl.offsetHeight; | |
91 | - paginationHeight += offsetHeight || 0; | |
92 | - } else { | |
93 | - // TODO First fix 24 | |
94 | - paginationHeight += 24; | |
95 | - } | |
96 | - } | |
70 | + const table = unref(tableElRef); | |
71 | + if (!table) return; | |
72 | + | |
73 | + const tableEl: Element = table.$el; | |
74 | + if (!tableEl) return; | |
75 | + const headEl = tableEl.querySelector('.ant-table-thead '); | |
97 | 76 | |
98 | - let footerHeight = 0; | |
99 | - if (!isBoolean(pagination)) { | |
100 | - if (!footerEl) { | |
101 | - footerEl = tableEl.querySelector('.ant-table-footer') as HTMLElement; | |
102 | - } else { | |
103 | - const offsetHeight = footerEl.offsetHeight; | |
104 | - footerHeight += offsetHeight || 0; | |
105 | - } | |
77 | + if (!headEl) return; | |
78 | + | |
79 | + // Table height from bottom | |
80 | + const { bottomIncludeBody } = getViewportOffset(headEl); | |
81 | + // Table height from bottom height-custom offset | |
82 | + | |
83 | + const paddingHeight = 32; | |
84 | + const borderHeight = 0; | |
85 | + // Pager height | |
86 | + let paginationHeight = 2; | |
87 | + if (!isBoolean(pagination)) { | |
88 | + if (!paginationEl) { | |
89 | + paginationEl = tableEl.querySelector('.ant-pagination') as HTMLElement; | |
90 | + } | |
91 | + if (paginationEl) { | |
92 | + const offsetHeight = paginationEl.offsetHeight; | |
93 | + paginationHeight += offsetHeight || 0; | |
94 | + } else { | |
95 | + // TODO First fix 24 | |
96 | + paginationHeight += 24; | |
106 | 97 | } |
98 | + } | |
107 | 99 | |
108 | - let headerHeight = 0; | |
109 | - if (headEl) { | |
110 | - headerHeight = (headEl as HTMLElement).offsetHeight; | |
100 | + let footerHeight = 0; | |
101 | + if (!isBoolean(pagination)) { | |
102 | + if (!footerEl) { | |
103 | + footerEl = tableEl.querySelector('.ant-table-footer') as HTMLElement; | |
104 | + } else { | |
105 | + const offsetHeight = footerEl.offsetHeight; | |
106 | + footerHeight += offsetHeight || 0; | |
111 | 107 | } |
108 | + } | |
112 | 109 | |
113 | - let height = | |
114 | - bottomIncludeBody - | |
115 | - (resizeHeightOffset || 0) - | |
116 | - paddingHeight - | |
117 | - borderHeight - | |
118 | - paginationHeight - | |
119 | - footerHeight - | |
120 | - headerHeight; | |
110 | + let headerHeight = 0; | |
111 | + if (headEl) { | |
112 | + headerHeight = (headEl as HTMLElement).offsetHeight; | |
113 | + } | |
121 | 114 | |
122 | - height = (height > maxHeight! ? (maxHeight as number) : height) ?? height; | |
123 | - setHeight(height); | |
115 | + let height = | |
116 | + bottomIncludeBody - | |
117 | + (resizeHeightOffset || 0) - | |
118 | + paddingHeight - | |
119 | + borderHeight - | |
120 | + paginationHeight - | |
121 | + footerHeight - | |
122 | + headerHeight; | |
124 | 123 | |
125 | - if (!bodyEl) { | |
126 | - bodyEl = tableEl.querySelector('.ant-table-body'); | |
127 | - } | |
128 | - bodyEl!.style.height = `${height}px`; | |
129 | - }, 200); | |
124 | + height = (height > maxHeight! ? (maxHeight as number) : height) ?? height; | |
125 | + setHeight(height); | |
126 | + | |
127 | + if (!bodyEl) { | |
128 | + bodyEl = tableEl.querySelector('.ant-table-body'); | |
129 | + } | |
130 | + | |
131 | + bodyEl!.style.height = `${height}px`; | |
130 | 132 | } |
131 | 133 | |
132 | - useWindowSizeFn(calcTableHeight, 200); | |
134 | + useWindowSizeFn(calcTableHeight, 280); | |
133 | 135 | |
134 | 136 | const getScrollX = computed(() => { |
135 | 137 | let width = 0; | ... | ... |