import { Ref, shallowRef } from 'vue'; import { PrivateRowDT, PrivateStkTableColumn, StkTableColumn } from './types'; import { getColWidth } from './utils/constRefUtils'; import { howDeepTheHeader } from './utils/index'; /** * Table Columns Processing Hook * Handles multi-level header processing and column flattening */ export function useTableColumns
>(virtualX: boolean, isRelativeMode: Ref) { /** * 表头.内容是 props.columns 的引用集合 * @eg * ```js * [ * [{dataIndex:'id',...}], // 第0行列配置 * [], // 第一行列配置 * //... * ] * ``` */ const tableHeaders = shallowRef[][]>([]); /** * 用于计算多级表头的tableHeaders。模拟rowSpan 位置的辅助数组。用于计算固定列。 */ const tableHeadersForCalc = shallowRef[][]>([]); /** * 处理多级表头 * @param columns 原始列配置 */ function dealColumns(columns: StkTableColumn
[]) { // reset const tableHeadersTemp: PrivateStkTableColumn[][] = []; const tableHeadersForCalcTemp: PrivateStkTableColumn[][] = []; let copyColumn: StkTableColumn
[] = columns; // do not deep clone // relative 模式下不支持sticky列。因此就放在左右两侧。 if (isRelativeMode.value) { const leftCol: StkTableColumn
[] = []; const centerCol: StkTableColumn
[] = []; const rightCol: StkTableColumn
[] = []; for (let i = 0, len = copyColumn.length; i < len; i++) { const col = copyColumn[i]; if (col.fixed === 'left') { leftCol.push(col); } else if (col.fixed === 'right') { rightCol.push(col); } else { centerCol.push(col); } } copyColumn = leftCol.concat(centerCol).concat(rightCol); } const maxDeep = howDeepTheHeader(copyColumn); for (let i = 0; i <= maxDeep; i++) { tableHeadersTemp[i] = []; tableHeadersForCalcTemp[i] = []; } /** 叶子列索引计数器,用于标注每个列在 tableHeaderLast 中的叶子范围 */ let leafIndex = 0; /** * flat columns * @param arr * @param depth 深度 * @param parent 父节点引用,用于构建双向链表。 */ function flat(arr: PrivateStkTableColumn[], parent: PrivateStkTableColumn | null, depth = 0): [number, number] { /** 所有子节点数量 */ let allChildrenLen = 0; let allChildrenWidthSum = 0; for (let i = 0, len = arr.length; i < len; i++) { const col = arr[i]; if (col.hidden) continue; col.__P__ = parent; col.__LF_S__ = leafIndex; /** 一列中的子节点数量 */ let colChildrenLen = 1; /** 多级表头的父节点宽度,通过叶子节点宽度计算得到 */ let colWidth = 0; if (col.children) { // DFS const [len, widthSum] = flat(col.children, col, depth + 1); colChildrenLen = len; colWidth = widthSum; tableHeadersForCalcTemp[depth].push(col); } else { colWidth = getColWidth(col); leafIndex++; for (let j = depth; j <= maxDeep; j++) { // 如有rowSpan 向下复制一个表头col,用于计算固定列 tableHeadersForCalcTemp[j].push(col); } } // 回溯 col.__LF_E__ = leafIndex; col.__W__ = colWidth; tableHeadersTemp[depth].push(col); const rowSpan = col.children ? 1 : maxDeep - depth + 1; const colSpan = colChildrenLen; if (rowSpan > 1) { col.__R_SP__ = rowSpan; } if (colSpan > 1) { col.__C_SP__ = colSpan; } allChildrenLen += colChildrenLen; allChildrenWidthSum += colWidth; } return [allChildrenLen, allChildrenWidthSum]; } flat(copyColumn as PrivateStkTableColumn[], null); tableHeaders.value = tableHeadersTemp; tableHeadersForCalc.value = tableHeadersForCalcTemp; } return [tableHeaders, tableHeadersForCalc, dealColumns] as const; }