diff --git a/src/components/common/TableHeader.vue b/src/components/common/TableHeader.vue index 4280b05..923755a 100644 --- a/src/components/common/TableHeader.vue +++ b/src/components/common/TableHeader.vue @@ -7,38 +7,17 @@ - - {{ c.label }} - + diff --git a/src/components/root/index.vue b/src/components/root/index.vue index 45984d1..76a3d6c 100644 --- a/src/components/root/index.vue +++ b/src/components/root/index.vue @@ -22,11 +22,7 @@ -
+
useResizeObserver(ganttRef.value?.$el, setGanttHeaders)); // #endregion // #region 加载示意线 -const { showLine, onDrag, lineLeft } = useDrag(); - -function onDownMidLine(e: PointerEvent) { - const rootRect = rootRef.value?.getBoundingClientRect(); - lineLeft.value = e.clientX - (rootRect?.left ?? 0); - $param.showMoveLine = true; -} +const { showLine, lineLeft, onResizeTableColumn } = useDrag(); const midLineRef = ref(null); -onMounted(() => { - onDrag(midLineRef, { - reset: true, - - onMove: (x, e) => { - const tableRect = tableRef.value?.$el.getBoundingClientRect(); - const ganttRect = ganttRef.value?.$el.getBoundingClientRect(); - - if (e.clientX < tableRect.left) { - return; - } - - if (e.clientX > ganttRect.right - 100) { - return; - } - - lineLeft.value = e.clientX; - }, - - onEnd: x => { - $param.showMoveLine = false; +onResizeTableColumn(midLineRef, { + onEnd: x => { + $slotsBox.tableHeaders.leafs[ + $slotsBox.tableHeaders.leafs.length - 1 + ].width = Math.max( + $slotsBox.tableHeaders.leafs[$slotsBox.tableHeaders.leafs.length - 1] + .width + x, + 20 + ); + }, + + preMove: (x, clientX) => { + const tableRect = tableRef.value?.$el.getBoundingClientRect(); + const ganttRect = ganttRef.value?.$el.getBoundingClientRect(); + + if ( + $slotsBox.tableHeaders.leafs[$slotsBox.tableHeaders.leafs.length - 1] + .width + + x < + 20 + ) + return false; + + if (clientX < tableRect.left) { + return false; + } - $slotsBox.tableHeaders.leafs[ - $slotsBox.tableHeaders.leafs.length - 1 - ].width += x; + if (clientX > ganttRect.right - 100) { + return false; } - }); + + return true; + } }); -// #endregion console.log('.....root', getCurrentInstance()); diff --git a/src/composables/useDrag.ts b/src/composables/useDrag.ts index 34e3b4a..bb26204 100644 --- a/src/composables/useDrag.ts +++ b/src/composables/useDrag.ts @@ -1,5 +1,6 @@ import { useDraggable } from '@vueuse/core'; -import { type Ref, ref, computed } from 'vue'; +import { type Ref, ref, computed, onMounted } from 'vue'; +import useElement from './useElement'; import useParam from './useParam'; const lineLeft = ref(0); @@ -7,6 +8,7 @@ const lineLeft = ref(0); interface DragOptions { onMove?: (x: number, e: MouseEvent) => void; onEnd?: (x: number, e: MouseEvent) => void; + onFinally?: () => void; target?: El; reset?: boolean; } @@ -42,16 +44,57 @@ export default () => { onEnd: (pos, e) => { if (isMove.value) options?.onEnd?.(left.value, e); + + options?.onFinally?.(); } }); } const { $param } = useParam(); + const { rootRef } = useElement(); + + function onResizeTableColumn( + el: Ref, + options: { + onEnd?: (x: number) => void; + preMove?: (x: number, clientX: number) => boolean; + } = {} + ) { + onMounted(() => { + const rootRect = rootRef.value?.getBoundingClientRect(); + + (el.value as HTMLElement)?.addEventListener('pointerdown', e => { + lineLeft.value = e.clientX - (rootRect?.left ?? 0); + $param.showMoveLine = true; + }); + + onDrag(el, { + reset: true, + + onMove: (x, e) => { + const clientX = e.clientX - (rootRect?.left ?? 0); + if (options?.preMove && !options?.preMove(x, clientX)) return; + + lineLeft.value = clientX; + }, + + onEnd: x => { + options?.onEnd?.(x); + }, + + onFinally: () => { + $param.showMoveLine = false; + } + }); + }); + } + const showLine = computed(() => $param.showMoveLine); return { onDrag, showLine, - lineLeft + lineLeft, + onResizeTableColumn }; }; diff --git a/src/models/param/header.ts b/src/models/param/header.ts index 33a15ff..1fdf859 100644 --- a/src/models/param/header.ts +++ b/src/models/param/header.ts @@ -28,6 +28,7 @@ class TableColumn extends Column { declare children?: TableColumn[]; parent?: TableColumn; width: number = Variables.default.tableColumnWidth; + isLast: boolean = false; /** * @@ -80,6 +81,7 @@ class Header { maxLevel = column.level; } } + if (column.children) { let colSpan = 0; column.children.forEach(subColumn => { @@ -159,12 +161,21 @@ class TableHeader extends Header { /** * This function idea from https://github.com/elemefe/element */ - private getAllColumns(columns: TableColumn[]) { + private getAllColumns(columns: TableColumn[], isLast?: boolean) { const result: TableColumn[] = []; - columns.forEach(column => { + columns.forEach((column, index) => { + if (index === columns.length - 1) { + if (isLast === undefined || isLast) { + column.isLast = true; + } + } + if (column.children) { result.push(column); - result.push.apply(result, this.getAllColumns(column.children)); + result.push.apply( + result, + this.getAllColumns(column.children, !!column.isLast) + ); } else { // 非叶子结点只接收 label 参数作为展示。叶子结点还可以展示 prop 参数值 if (!column.label) column.label = column.node.props?.prop ?? '';