What problem does this feature solve?
在实际业务中,表格列经常会通过多级表头分组来组织(例如:"销售" 分组下有 "Q1"、"Q2","市场" 分组下也有 "Q1"、"Q2")。目前 ListTable.dragOrder.dragHeaderMode 只支持同一层级或同一分组内的列顺序调整,无法直接将一个分组下的列拖拽到另一个分组下,也无法拖拽整个分组来改变其位置。
这就导致开发者必须自己额外实现一套列管理 UI(比如侧边栏树形拖拽),然后手动调用 table.setColumns(newColumns) 来更新表格。这样做的问题在于:
- 用户需要在两套交互之间切换,体验割裂;
- 拖拽提示、占位线、阴影等视觉效果都需要自行实现,成本高;
- 很难做到和 VTable 原生拖拽一致的手感。
期望的交互体验:
用户可以将某个分组下的叶子列(如 "销售-Q1")直接拖拽到另一个分组(如 "市场")下;
- 用户可以拖拽整个分组表头,调整顶层分组的顺序;
- 尽量复用现有 dragOrder 的拖拽视觉反馈(阴影、插入指示线、冻结列处理等)。
- 这种需求在数据分析平台、报表设计器、可配置表格等场景中非常常见。
What does the proposed API look like?
- 扩展现有 dragOrder 配置
可以在现有 dragHeaderMode 基础上增加跨分组拖拽能力,或者新增一个配置项:
interface DragOrderConfig {
dragHeaderMode?: 'none' | 'all' | 'column' | 'row';
// 新增:是否允许跨分组/跨层级拖拽
allowCrossGroupDrag?: boolean;
// 现有选项
frozenColDragHeaderMode?: 'disabled' | 'adjustFrozenCount' | 'fixedFrozenCount';
validateDragOrderOnEnd?: (source: CellAddress, target: CellAddress) => boolean;
}
- 行为说明
当 allowCrossGroupDrag: true 时:
叶子列可以拖拽到另一个分组的子列位置;
顶层分组表头可以被拖拽,用于调整分组顺序;
拖拽完成后,表格内部自动重组 columns 的嵌套结构;
validateDragOrderOnEnd 仍然生效,返回 false 时取消此次拖拽。
- 使用示例
const table = new ListTable({
container: document.getElementById('container'),
records: data,
columns: [
{
title: '销售',
children: [
{ field: 'sales_q1', title: 'Q1' },
{ field: 'sales_q2', title: 'Q2' },
],
},
{
title: '市场',
children: [
{ field: 'mkt_q1', title: 'Q1' },
{ field: 'mkt_q2', title: 'Q2' },
],
},
],
dragOrder: {
dragHeaderMode: 'column',
allowCrossGroupDrag: true,
frozenColDragHeaderMode: 'fixedFrozenCount',
},
});
What problem does this feature solve?
在实际业务中,表格列经常会通过多级表头分组来组织(例如:"销售" 分组下有 "Q1"、"Q2","市场" 分组下也有 "Q1"、"Q2")。目前 ListTable.dragOrder.dragHeaderMode 只支持同一层级或同一分组内的列顺序调整,无法直接将一个分组下的列拖拽到另一个分组下,也无法拖拽整个分组来改变其位置。
这就导致开发者必须自己额外实现一套列管理 UI(比如侧边栏树形拖拽),然后手动调用 table.setColumns(newColumns) 来更新表格。这样做的问题在于:
期望的交互体验:
用户可以将某个分组下的叶子列(如 "销售-Q1")直接拖拽到另一个分组(如 "市场")下;
What does the proposed API look like?
可以在现有 dragHeaderMode 基础上增加跨分组拖拽能力,或者新增一个配置项:
interface DragOrderConfig {
dragHeaderMode?: 'none' | 'all' | 'column' | 'row';
// 新增:是否允许跨分组/跨层级拖拽
allowCrossGroupDrag?: boolean;
// 现有选项
frozenColDragHeaderMode?: 'disabled' | 'adjustFrozenCount' | 'fixedFrozenCount';
validateDragOrderOnEnd?: (source: CellAddress, target: CellAddress) => boolean;
}
当 allowCrossGroupDrag: true 时:
叶子列可以拖拽到另一个分组的子列位置;
顶层分组表头可以被拖拽,用于调整分组顺序;
拖拽完成后,表格内部自动重组 columns 的嵌套结构;
validateDragOrderOnEnd 仍然生效,返回 false 时取消此次拖拽。
const table = new ListTable({
container: document.getElementById('container'),
records: data,
columns: [
{
title: '销售',
children: [
{ field: 'sales_q1', title: 'Q1' },
{ field: 'sales_q2', title: 'Q2' },
],
},
{
title: '市场',
children: [
{ field: 'mkt_q1', title: 'Q1' },
{ field: 'mkt_q2', title: 'Q2' },
],
},
],
dragOrder: {
dragHeaderMode: 'column',
allowCrossGroupDrag: true,
frozenColDragHeaderMode: 'fixedFrozenCount',
},
});