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,7 +66,7 @@ | ||
66 | const headerRef = ref<ComponentRef>(null); | 66 | const headerRef = ref<ComponentRef>(null); |
67 | const footerRef = ref<ComponentRef>(null); | 67 | const footerRef = ref<ComponentRef>(null); |
68 | const footerHeight = ref(0); | 68 | const footerHeight = ref(0); |
69 | - const { prefixCls } = useDesign('page-wrapper'); | 69 | + const { prefixCls, prefixVar } = useDesign('page-wrapper'); |
70 | const { contentHeight, setPageHeight, pageHeight } = usePageContext(); | 70 | const { contentHeight, setPageHeight, pageHeight } = usePageContext(); |
71 | 71 | ||
72 | const getClass = computed(() => { | 72 | const getClass = computed(() => { |
@@ -110,40 +110,39 @@ | @@ -110,40 +110,39 @@ | ||
110 | } | 110 | } |
111 | nextTick(() => { | 111 | nextTick(() => { |
112 | //fix:in contentHeight mode: delay getting footer and header dom element to get the correct height | 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 | immediate: true, | 146 | immediate: true, |
148 | } | 147 | } |
149 | ); | 148 | ); |
@@ -171,6 +170,7 @@ | @@ -171,6 +170,7 @@ | ||
171 | .@{prefix-cls}-content { | 170 | .@{prefix-cls}-content { |
172 | margin: 16px 16px 0 16px; | 171 | margin: 16px 16px 0 16px; |
173 | } | 172 | } |
173 | + | ||
174 | .ant-page-header { | 174 | .ant-page-header { |
175 | &:empty { | 175 | &:empty { |
176 | padding: 0; | 176 | padding: 0; |
src/components/Table/src/BasicTable.vue
@@ -161,7 +161,8 @@ | @@ -161,7 +161,8 @@ | ||
161 | getProps, | 161 | getProps, |
162 | tableElRef, | 162 | tableElRef, |
163 | getColumnsRef, | 163 | getColumnsRef, |
164 | - getRowSelectionRef | 164 | + getRowSelectionRef, |
165 | + getDataSourceRef | ||
165 | ); | 166 | ); |
166 | 167 | ||
167 | const { customRow } = useCustomRow(getProps, { | 168 | const { customRow } = useCustomRow(getProps, { |
src/components/Table/src/hooks/useTableScroll.ts
@@ -14,14 +14,15 @@ export function useTableScroll( | @@ -14,14 +14,15 @@ export function useTableScroll( | ||
14 | propsRef: ComputedRef<BasicTableProps>, | 14 | propsRef: ComputedRef<BasicTableProps>, |
15 | tableElRef: Ref<ComponentRef>, | 15 | tableElRef: Ref<ComponentRef>, |
16 | columnsRef: ComputedRef<BasicColumn[]>, | 16 | columnsRef: ComputedRef<BasicColumn[]>, |
17 | - rowSelectionRef: ComputedRef<TableRowSelection<any> | null> | 17 | + rowSelectionRef: ComputedRef<TableRowSelection<any> | null>, |
18 | + getDataSourceRef: ComputedRef<Recordable[]> | ||
18 | ) { | 19 | ) { |
19 | const tableHeightRef: Ref<Nullable<number>> = ref(null); | 20 | const tableHeightRef: Ref<Nullable<number>> = ref(null); |
20 | 21 | ||
21 | const modalFn = useModalContext(); | 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 | const getCanResize = computed(() => { | 27 | const getCanResize = computed(() => { |
27 | const { canResize, scroll } = unref(propsRef); | 28 | const { canResize, scroll } = unref(propsRef); |
@@ -34,6 +35,7 @@ export function useTableScroll( | @@ -34,6 +35,7 @@ export function useTableScroll( | ||
34 | debounceRedoHeight(); | 35 | debounceRedoHeight(); |
35 | }, | 36 | }, |
36 | { | 37 | { |
38 | + flush: 'post', | ||
37 | immediate: true, | 39 | immediate: true, |
38 | } | 40 | } |
39 | ); | 41 | ); |
@@ -59,77 +61,77 @@ export function useTableScroll( | @@ -59,77 +61,77 @@ export function useTableScroll( | ||
59 | 61 | ||
60 | async function calcTableHeight() { | 62 | async function calcTableHeight() { |
61 | const { resizeHeightOffset, pagination, maxHeight } = unref(propsRef); | 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 | await nextTick(); | 68 | await nextTick(); |
65 | //Add a delay to get the correct bottomIncludeBody paginationHeight footerHeight headerHeight | 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 | const getScrollX = computed(() => { | 136 | const getScrollX = computed(() => { |
135 | let width = 0; | 137 | let width = 0; |