From 28d3484f073a52c83b102cdf18f76ab33246ac73 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Tue, 28 Jul 2026 21:06:08 +0800 Subject: [PATCH 1/4] fix(vtable): expose auto row real height --- .../issue-5117-auto-height-real-height.ts | 70 +++++++++++++++++++ packages/vtable/examples/menu.ts | 4 ++ .../scenegraph/layout/compute-row-height.ts | 28 ++++++-- packages/vtable/src/ts-types/base-table.ts | 6 +- 4 files changed, 102 insertions(+), 6 deletions(-) create mode 100644 packages/vtable/examples/debug/issue-5117-auto-height-real-height.ts diff --git a/packages/vtable/examples/debug/issue-5117-auto-height-real-height.ts b/packages/vtable/examples/debug/issue-5117-auto-height-real-height.ts new file mode 100644 index 0000000000..77e3099a91 --- /dev/null +++ b/packages/vtable/examples/debug/issue-5117-auto-height-real-height.ts @@ -0,0 +1,70 @@ +import * as VTable from '../../src'; + +const CONTAINER_ID = 'vTable'; + +const records = Array.from({ length: 60 }, (_, index) => ({ + id: index + 1, + name: `row-${index + 1}`, + desc: + index % 3 === 0 + ? 'long text long text long text long text long text long text long text long text long text' + : 'short' +})); + +export function createTable() { + const container = document.getElementById(CONTAINER_ID)!; + document.getElementById('issue5117Toolbar')?.remove(); + container.style.width = '760px'; + container.style.height = '420px'; + + const toolbar = document.createElement('div'); + toolbar.id = 'issue5117Toolbar'; + toolbar.style.cssText = 'height: 48px; font-size: 12px; display: flex; gap: 12px; align-items: center;'; + toolbar.innerHTML = ` + + + `; + container.before(toolbar); + + const realHeights: Array = []; + const tableInstance = new VTable.ListTable({ + container, + records, + columns: [ + { field: 'id', title: 'ID', width: 80 }, + { field: 'name', title: 'Name', width: 120 }, + { + field: 'desc', + title: 'Description', + width: 280, + style: { + autoWrapText: true + } + } + ], + widthMode: 'standard', + heightMode: 'autoHeight', + defaultRowHeight: 64, + customComputeRowHeight: ({ row, realHeight }) => { + realHeights[row] = realHeight; + return 'auto'; + } + }); + + const check = () => { + const bodyRow = tableInstance.columnHeaderLevelCount + 1; + const realHeight = realHeights[bodyRow]; + const rowHeight = tableInstance.getRowHeight(bodyRow); + const pass = typeof realHeight === 'number' && realHeight >= 64 && rowHeight >= 64; + const state = document.getElementById('issue5117State')!; + state.textContent = `${pass ? 'PASS' : 'FAIL'} | realHeight=${realHeight} rowHeight=${rowHeight}`; + return { pass, realHeight, rowHeight }; + }; + + document.getElementById('issue5117Check')!.addEventListener('click', check); + + window.tableInstance = tableInstance; + (window as any).issue5117Check = check; + + setTimeout(check, 0); +} diff --git a/packages/vtable/examples/menu.ts b/packages/vtable/examples/menu.ts index 13b2c16107..0287f9b0ec 100644 --- a/packages/vtable/examples/menu.ts +++ b/packages/vtable/examples/menu.ts @@ -34,6 +34,10 @@ export const menus = [ path: 'debug', name: 'issue-5114' }, + { + path: 'debug', + name: 'issue-5117-auto-height-real-height' + }, { path: 'debug', name: 'issue-5146' diff --git a/packages/vtable/src/scenegraph/layout/compute-row-height.ts b/packages/vtable/src/scenegraph/layout/compute-row-height.ts index 067ce3f2fb..7d51230ad3 100644 --- a/packages/vtable/src/scenegraph/layout/compute-row-height.ts +++ b/packages/vtable/src/scenegraph/layout/compute-row-height.ts @@ -351,7 +351,22 @@ export function computeRowsHeight( } } +const limitMinRowHeight = (height: number, row: number, table: BaseTableAPI): number => { + const defaultHeight = table.getDefaultRowHeight(row); + return isNumber(defaultHeight) ? Math.max(height, defaultHeight) : height; +}; + export function computeRowHeight(row: number, startCol: number, endCol: number, table: BaseTableAPI): number { + return computeRowHeightInternal(row, startCol, endCol, table, true); +} + +function computeRowHeightInternal( + row: number, + startCol: number, + endCol: number, + table: BaseTableAPI, + enableCustomCompute: boolean +): number { const isAllRowsAuto = table.isAutoRowHeight(row) || (table.heightMode === 'adaptive' && table.options.autoHeightInAdaptiveMode !== false); if (!isAllRowsAuto && table.getDefaultRowHeight(row) !== 'auto') { @@ -359,16 +374,19 @@ export function computeRowHeight(row: number, startCol: number, endCol: number, } let maxHeight; - if (table.options.customComputeRowHeight) { + if (enableCustomCompute && table.options.customComputeRowHeight) { + const realHeight = computeRowHeightInternal(row, startCol, endCol, table, false); const customRowHeight = table.options.customComputeRowHeight({ row, - table + table, + realHeight }); if (typeof customRowHeight === 'number') { return customRowHeight; - } else if (customRowHeight !== 'auto') { - return table.getDefaultRowHeight(row) as number; + } else if (customRowHeight === 'auto' || customRowHeight === undefined) { + return realHeight; } + return table.getDefaultRowHeight(row) as number; } if (table.internalProps.rowHeightConfig) { const rowHeightConfig = table.internalProps.rowHeightConfig.find((item: { key: number }) => item.key === row); @@ -462,7 +480,7 @@ export function computeRowHeight(row: number, startCol: number, endCol: number, maxHeight = isValid(maxHeight) ? Math.max(textHeight, maxHeight) : textHeight; } if (isValid(maxHeight)) { - return maxHeight; + return limitMinRowHeight(maxHeight, row, table); } const defaultHeight = table.getDefaultRowHeight(row); diff --git a/packages/vtable/src/ts-types/base-table.ts b/packages/vtable/src/ts-types/base-table.ts index 5433438e5c..f898856f68 100644 --- a/packages/vtable/src/ts-types/base-table.ts +++ b/packages/vtable/src/ts-types/base-table.ts @@ -694,7 +694,11 @@ export interface BaseTableConstructorOptions { renderOption?: any; formatCopyValue?: (value: string) => string; - customComputeRowHeight?: (computeArgs: { row: number; table: BaseTableAPI }) => number | 'auto' | undefined; + customComputeRowHeight?: (computeArgs: { + row: number; + table: BaseTableAPI; + realHeight?: number; + }) => number | 'auto' | undefined; /** 当表格出现抖动情况,请排查是否上层dom容器的宽高是小数引起的。如果不能保证是整数,请配置这个配置项为true */ tableSizeAntiJitter?: boolean; From 5146a6d45e20ac32fce7b9cf7e762985801ddb90 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Wed, 29 Jul 2026 10:57:19 +0800 Subject: [PATCH 2/4] fix(vtable): preserve custom row height semantics --- .../scenegraph/layout/compute-row-height.ts | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/packages/vtable/src/scenegraph/layout/compute-row-height.ts b/packages/vtable/src/scenegraph/layout/compute-row-height.ts index 7d51230ad3..81feacf957 100644 --- a/packages/vtable/src/scenegraph/layout/compute-row-height.ts +++ b/packages/vtable/src/scenegraph/layout/compute-row-height.ts @@ -375,16 +375,29 @@ function computeRowHeightInternal( let maxHeight; if (enableCustomCompute && table.options.customComputeRowHeight) { - const realHeight = computeRowHeightInternal(row, startCol, endCol, table, false); - const customRowHeight = table.options.customComputeRowHeight({ + let realHeight: number; + let hasRealHeight = false; + const getRealHeight = () => { + if (!hasRealHeight) { + realHeight = computeRowHeightInternal(row, startCol, endCol, table, false); + hasRealHeight = true; + } + return realHeight; + }; + const computeArgs = { row, - table, - realHeight + table + } as Parameters>[0]; + Object.defineProperty(computeArgs, 'realHeight', { + get: getRealHeight, + enumerable: true, + configurable: true }); + const customRowHeight = table.options.customComputeRowHeight(computeArgs); if (typeof customRowHeight === 'number') { return customRowHeight; - } else if (customRowHeight === 'auto' || customRowHeight === undefined) { - return realHeight; + } else if (customRowHeight === 'auto') { + return getRealHeight(); } return table.getDefaultRowHeight(row) as number; } From 8711969f9e3bdcb7cad7f76d11332f3474efd4b0 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Wed, 29 Jul 2026 11:35:29 +0800 Subject: [PATCH 3/4] fix(vtable): avoid global auto row min height --- .../examples/debug/issue-5117-auto-height-real-height.ts | 8 ++++---- .../vtable/src/scenegraph/layout/compute-row-height.ts | 7 +------ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/vtable/examples/debug/issue-5117-auto-height-real-height.ts b/packages/vtable/examples/debug/issue-5117-auto-height-real-height.ts index 77e3099a91..c9384317c9 100644 --- a/packages/vtable/examples/debug/issue-5117-auto-height-real-height.ts +++ b/packages/vtable/examples/debug/issue-5117-auto-height-real-height.ts @@ -27,6 +27,7 @@ export function createTable() { container.before(toolbar); const realHeights: Array = []; + const minRowHeight = 64; const tableInstance = new VTable.ListTable({ container, records, @@ -44,18 +45,17 @@ export function createTable() { ], widthMode: 'standard', heightMode: 'autoHeight', - defaultRowHeight: 64, customComputeRowHeight: ({ row, realHeight }) => { realHeights[row] = realHeight; - return 'auto'; + return Math.max(realHeight ?? 0, minRowHeight); } }); const check = () => { - const bodyRow = tableInstance.columnHeaderLevelCount + 1; + const bodyRow = tableInstance.columnHeaderLevelCount; const realHeight = realHeights[bodyRow]; const rowHeight = tableInstance.getRowHeight(bodyRow); - const pass = typeof realHeight === 'number' && realHeight >= 64 && rowHeight >= 64; + const pass = typeof realHeight === 'number' && rowHeight === Math.max(realHeight, minRowHeight); const state = document.getElementById('issue5117State')!; state.textContent = `${pass ? 'PASS' : 'FAIL'} | realHeight=${realHeight} rowHeight=${rowHeight}`; return { pass, realHeight, rowHeight }; diff --git a/packages/vtable/src/scenegraph/layout/compute-row-height.ts b/packages/vtable/src/scenegraph/layout/compute-row-height.ts index 81feacf957..cf495d6e68 100644 --- a/packages/vtable/src/scenegraph/layout/compute-row-height.ts +++ b/packages/vtable/src/scenegraph/layout/compute-row-height.ts @@ -351,11 +351,6 @@ export function computeRowsHeight( } } -const limitMinRowHeight = (height: number, row: number, table: BaseTableAPI): number => { - const defaultHeight = table.getDefaultRowHeight(row); - return isNumber(defaultHeight) ? Math.max(height, defaultHeight) : height; -}; - export function computeRowHeight(row: number, startCol: number, endCol: number, table: BaseTableAPI): number { return computeRowHeightInternal(row, startCol, endCol, table, true); } @@ -493,7 +488,7 @@ function computeRowHeightInternal( maxHeight = isValid(maxHeight) ? Math.max(textHeight, maxHeight) : textHeight; } if (isValid(maxHeight)) { - return limitMinRowHeight(maxHeight, row, table); + return maxHeight; } const defaultHeight = table.getDefaultRowHeight(row); From de79c407c71b0d9ef97a13f76bf6bd8ff9d83356 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Wed, 29 Jul 2026 14:06:46 +0800 Subject: [PATCH 4/4] fix(vtable): keep real height getter non-enumerable --- packages/vtable/src/scenegraph/layout/compute-row-height.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vtable/src/scenegraph/layout/compute-row-height.ts b/packages/vtable/src/scenegraph/layout/compute-row-height.ts index cf495d6e68..dade83a49b 100644 --- a/packages/vtable/src/scenegraph/layout/compute-row-height.ts +++ b/packages/vtable/src/scenegraph/layout/compute-row-height.ts @@ -385,7 +385,7 @@ function computeRowHeightInternal( } as Parameters>[0]; Object.defineProperty(computeArgs, 'realHeight', { get: getRealHeight, - enumerable: true, + enumerable: false, configurable: true }); const customRowHeight = table.options.customComputeRowHeight(computeArgs);