From 4138d3c822106b6d92e39cb19874d1e799f18c85 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Fri, 19 Apr 2024 19:14:18 +0800 Subject: [PATCH] fix: tabs size error, close #7491 #7482 --- components/tabs/src/TabNavList/index.tsx | 67 ++++++++++++++++++------ 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/components/tabs/src/TabNavList/index.tsx b/components/tabs/src/TabNavList/index.tsx index 36a798aca..ca3efe7fb 100644 --- a/components/tabs/src/TabNavList/index.tsx +++ b/components/tabs/src/TabNavList/index.tsx @@ -64,6 +64,34 @@ interface ExtraContentProps { extra?: (info?: { position: 'left' | 'right' }) => TabBarExtraContent; } +const getTabSize = (tab: HTMLElement, containerRect: { x: number; y: number }) => { + // tabListRef + const { offsetWidth, offsetHeight, offsetTop, offsetLeft } = tab; + const { width, height, x, y } = tab.getBoundingClientRect(); + + // Use getBoundingClientRect to avoid decimal inaccuracy + if (Math.abs(width - offsetWidth) < 1) { + return [width, height, x - containerRect.x, y - containerRect.y]; + } + + return [offsetWidth, offsetHeight, offsetLeft, offsetTop]; +}; + +// const getSize = (refObj: ShallowRef) => { +// const { offsetWidth = 0, offsetHeight = 0 } = refObj.value || {}; + +// // Use getBoundingClientRect to avoid decimal inaccuracy +// if (refObj.value) { +// const { width, height } = refObj.value.getBoundingClientRect(); + +// if (Math.abs(width - offsetWidth) < 1) { +// return [width, height]; +// } +// } + +// return [offsetWidth, offsetHeight]; +// }; + export default defineComponent({ compatConfig: { MODE: 3 }, name: 'TabNavList', @@ -288,7 +316,29 @@ export default defineComponent({ return ([visibleStart.value, visibleEnd.value] = [startIndex, endIndex]); }); + const updateTabSizes = () => { + setTabSizes(() => { + const newSizes: TabSizeMap = new Map(); + const listRect = tabListRef.value?.getBoundingClientRect(); + tabs.value.forEach(({ key }) => { + const btnRef = btnRefs.value.get(key); + const btnNode = (btnRef as any)?.$el || btnRef; + if (btnNode) { + const [width, height, left, top] = getTabSize(btnNode, listRect); + newSizes.set(key, { width, height, left, top }); + } + }); + return newSizes; + }); + }; + watch( + () => tabs.value.map(tab => tab.key).join('%%'), + () => { + updateTabSizes(); + }, + { flush: 'post' }, + ); const onListHolderResize = () => { // Update wrapper records const offsetWidth = tabsWrapperRef.value?.offsetWidth || 0; @@ -308,22 +358,7 @@ export default defineComponent({ setWrapperScrollHeight(newWrapperScrollHeight); // Update buttons records - setTabSizes(() => { - const newSizes: TabSizeMap = new Map(); - tabs.value.forEach(({ key }) => { - const btnRef = btnRefs.value.get(key); - const btnNode = (btnRef as any)?.$el || btnRef; - if (btnNode) { - newSizes.set(key, { - width: btnNode.offsetWidth, - height: btnNode.offsetHeight, - left: btnNode.offsetLeft, - top: btnNode.offsetTop, - }); - } - }); - return newSizes; - }); + updateTabSizes(); }; // ======================== Dropdown =======================