Lzh on GitHub

表格状态 (Vue) 指南

示例

想要跳过直接看实现?请查看这些示例:

列排序指南

默认情况下,列按照它们在 columns 数组中定义的顺序进行排序。但是,您可以使用 columnOrder 状态手动指定列顺序。其他功能,如列固定和分组,也可能影响列顺序。

什么会影响列顺序

有 3 个表格功能可以重新排序列,它们的发生顺序如下:

  1. 列固定:如果启用了固定功能,列会被分为左侧、中央(未固定)和右侧固定列。
  2. 手动列排序:应用手动指定的列顺序。
  3. 分组:如果启用了分组,并且分组状态处于活动状态,并且 tableOptions.groupedColumnMode 设置为 'reorder' | 'remove',那么分组的列会被重新排序到列流的开头。

注意:如果与列固定结合使用,columnOrder 状态将只影响未固定的列。

列顺序状态

如果您不提供 columnOrder 状态,TanStack Table 将只使用 columns 数组中列的顺序。但是,您可以向 columnOrder 状态提供一个字符串列 ID 数组,以指定列的顺序。

默认列顺序

如果您只需要指定初始列顺序,您只需在 initialState 表选项中指定 columnOrder 状态即可。

const table = useReactTable({
  //...
  initialState: {
    columnOrder: ['columnId1', 'columnId2', 'columnId3'],
  }
  //...
});

注意:如果您使用 state 表选项也指定了 columnOrder 状态,那么 initialState 将不起作用。对于特定状态,只能在 initialStatestate 中的一个地方进行指定,不要两者都用。

管理列顺序状态

如果您需要动态更改列顺序,或者在表格初始化后设置列顺序,您可以像管理任何其他表格状态一样管理 columnOrder 状态。

const [columnOrder, setColumnOrder] = useState<string[]>(['columnId1', 'columnId2', 'columnId3']); // 可选地初始化列顺序

//...

const table = useReactTable({
  //...
  state: {
    columnOrder,
    //...
  }
  onColumnOrderChange: setColumnOrder,
  //...
});

重新排序列

如果表格有允许用户重新排序列的 UI,您可以像这样设置逻辑:

const [columnOrder, setColumnOrder] = useState<string[]>(columns.map(c => c.id));

// 根据您选择的 DND 解决方案,您可能需要或可能不需要这样的状态
const [movingColumnId, setMovingColumnId] = useState<string | null>(null);
const [targetColumnId, setTargetColumnId] = useState<string | null>(null);

// 用于拼接和重新排序 columnOrder 数组的实用函数
const reorderColumn = <TData extends RowData>(
  movingColumnId: Column<TData>,
  targetColumnId: Column<TData>,
): string[] => {
  const newColumnOrder = [...columnOrder];
  newColumnOrder.splice(
    newColumnOrder.indexOf(targetColumnId),
    0,
    newColumnOrder.splice(newColumnOrder.indexOf(movingColumnId), 1)[0],
  );
  setColumnOrder(newColumnOrder);
};

const handleDragEnd = (e: DragEvent) => {
  if(!movingColumnId || !targetColumnId) return;
  setColumnOrder(reorderColumn(movingColumnId, targetColumnId));
};

// 使用您选择的 DND 解决方案

拖放列重新排序建议 (React)

毫无疑问,有许多方法可以与 TanStack Table 一起实现拖放功能。这里有一些建议,以避免您遇到不愉快的经历:

  • 请勿尝试使用 "react-dnd" 如果您正在使用 React 18 或更高版本。React DnD 在其时代是一个重要的库,但它现在不经常更新,并且与 React 18 存在不兼容性,尤其是在 React 严格模式下。尽管仍然可以使其工作,但有更新的替代方案具有更好的兼容性并得到更积极的维护。React DnD 的 Provider 也可能干扰并冲突您可能在应用程序中尝试的任何其他 DnD 解决方案。
  • 使用 "@dnd-kit/core"。DnD Kit 是一个现代、模块化且轻量级的拖放库,与现代 React 生态系统高度兼容,并且与语义化的 <table> 标记配合良好。官方的两个 TanStack DnD 示例(列 DnD行 DnD)现在都使用 DnD Kit。
  • 考虑其他 DnD 库,如 "react-beautiful-dnd",但请注意它们可能较大的包大小、维护状态以及与 <table> 标记的兼容性。
  • 考虑使用原生浏览器事件和状态管理来实现轻量级拖放功能。但是,请注意,如果您不额外努力实现适当的触摸事件,这种方法可能不适合移动用户。Material React Table V2 是一个示例库,它仅使用浏览器拖放事件(如 onDragStartonDragEndonDragEnter)而没有其他依赖项来实现 TanStack Table。浏览其源代码以了解其实现方式。