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);