vue甘特图组件 vxe-gantt 实现拖拽任务自动更新紧前紧后依赖线关联任务的日期

在项目管理甘特图中,任务之间往往存在复杂的依赖关系。当用户拖拽某个任务调整日期时,如果其前置或后置任务没有同步更新,就会破坏依赖逻辑,导致计划失真。vxe-gantt 提供了 taskBarMoveConfig.isSyncLinkTask 配置项,可以自动根据依赖线更新关联任务的日期,确保甘特图始终符合紧前紧后约束。

本文将详细介绍该功能的启用方式、移动规则、完整示例代码及注意事项。

功能概述

启用 isSyncLinkTask 后,拖拽任务条移动日期时,vxe-gantt 会:

  • 自动识别该任务的前置任务(紧前)和后置任务(紧后)。
  • 根据依赖类型(如完成-开始)重新计算受影响任务的日期。
  • 逐层传播变更,直到所有关联任务都满足约束。
  • 保证甘特图数据的一致性,避免手动逐个调整。

核心配置

在 taskBarMoveConfig 中开启 isSyncLinkTask:

taskBarMoveConfig: {
  isSyncLinkTask: true // 拖拽移动任务后自动更新依赖线关联任务的日期
}

同时,为了允许拖拽移动和创建依赖线,还需要以下配置:

taskBarConfig: {
  moveable: true,      // 允许拖拽任务移动日期
  resizable: true,     // 允许拖拽任务调整日期
  linkCreatable: true  // 允许自定义创建依赖线
},
taskLinkConfig: {
  isHover: true,           // 鼠标悬停高亮依赖线
  isCurrent: true,         // 点击高亮依赖线
  isDblclickToRemove: true // 双击依赖线删除
}

依赖关系通过 links 数组定义,并使用 VxeGanttDependencyType 指定类型。

移动规则详解

vxe-gantt 的自动同步逻辑遵循以下规则,确保依赖关系不被破坏:

1. 向右拖拽

  • 紧前任务:不动,也不检查。
  • 紧后任务:按照依赖约束重新计算日期,并逐层向下传播。
  • 例如,若任务 A 完成-开始依赖于任务 B,当 A 向右移动(延后)时,B 必须相应延后,以保证 B 在 A 完成后开始。

2. 向左拖拽

  • 紧前任务:不动,但需要检查并钳制。即如果当前任务向左移动后,其开始时间早于紧前任务的完成时间,则会被约束限制,不能继续左移。
  • 紧后任务:按照依赖约束重新计算日期,并逐层向下传播。

3. 传播核心逻辑

每一层传播时:

  • 先跟随直接紧前的实际位移:即后置任务先按前置任务的位移量移动。
  • 再满足所有紧前约束:检查该任务是否满足所有前置依赖,若不满足则调整到满足为止。
  • 变了才继续传,没变就停:如果某任务日期未发生变化,则不再向后传播,避免无限循环。

这套机制保证了拖拽操作既能灵活调整,又能自动维护依赖完整性。

代码

extend_gantt_chart_gantt_dependency_move_update

<template>
  <div>
    <vxe-gantt v-bind="ganttOptions"></vxe-gantt>
  </div>
</template>

<script setup>
import { reactive } from 'vue'
import { VxeGanttDependencyType } from 'vxe-gantt'

const ganttOptions = reactive({
  border: true,
  height: 600,
  columnConfig: {
    resizable: true
  },
  rowConfig: {
    keyField: 'id' // 行主键
  },
  taskBarConfig: {
    showProgress: true, // 是否显示进度条
    showContent: true, // 是否在任务条显示内容
    moveable: true, // 是否允许拖拽任务移动日期
    resizable: true, // 是否允许拖拽任务调整日期
    linkCreatable: true, // 是否允许自定义创建依赖线
    barStyle: {
      round: true, // 圆角
      bgColor: '#fca60b', // 任务条的背景颜色
      completedBgColor: '#65c16f' // 已完成部分任务条的背景颜色
    }
  },
  taskLinkConfig: {
    isHover: true, // 当鼠标移到依赖线时,是否要高亮当前依赖线
    isCurrent: true, // 当鼠标点击依赖线时,是否要高亮当前依赖线
    isDblclickToRemove: true // 是否允许双击依赖线删除
  },
  taskViewConfig: {
    tableStyle: {
      width: 480 // 表格宽度
    }
  },
  taskBarMoveConfig: {
    isSyncLinkTask: true // 拖拽移动任务后自动更新依赖线关联任务的日期
  },
  links: [
    { from: 20001, to: 20002, type: VxeGanttDependencyType.FinishToStart },
    { from: 20001, to: 20003, type: VxeGanttDependencyType.FinishToStart },
    { from: 20002, to: 20004, type: VxeGanttDependencyType.FinishToStart },
    { from: 20003, to: 20005, type: VxeGanttDependencyType.FinishToStart },
    { from: 20004, to: 20006, type: VxeGanttDependencyType.FinishToStart },
    { from: 20005, to: 20006, type: VxeGanttDependencyType.FinishToStart },
    { from: 20006, to: 20007, type: VxeGanttDependencyType.FinishToStart },
    { from: 20007, to: 20008, type: VxeGanttDependencyType.FinishToStart },
    { from: 20008, to: 20009, type: VxeGanttDependencyType.FinishToStart },
    { from: 20009, to: 20010, type: VxeGanttDependencyType.FinishToStart }
  ],
  columns: [
    { type: 'seq', width: 70 },
    { field: 'title', title: '任务名称' },
    { field: 'start', title: '开始时间', width: 100 },
    { field: 'end', title: '结束时间', width: 100 },
    { field: 'progress', title: '进度(%)', width: 80 }
  ],
  data: [
    { id: 20001, title: '需求分析', start: '2025-01-06', end: '2025-01-08', progress: 100 },
    { id: 20002, title: 'UI设计', start: '2025-01-09', end: '2025-01-13', progress: 100 },
    { id: 20003, title: '数据库设计', start: '2025-01-09', end: '2025-01-11', progress: 100 },
    { id: 20004, title: '前端开发', start: '2025-01-16', end: '2025-01-20', progress: 70 },
    { id: 20005, title: '后端开发', start: '2025-01-12', end: '2025-01-20', progress: 80 },
    { id: 20006, title: '接口联调', start: '2025-01-21', end: '2025-01-23', progress: 30 },
    { id: 20007, title: '功能测试', start: '2025-01-24', end: '2025-01-27', progress: 0 },
    { id: 20008, title: '性能优化', start: '2025-01-29', end: '2025-01-31', progress: 0 },
    { id: 20009, title: '部署上线', start: '2025-02-01', end: '2025-02-04', progress: 0 },
    { id: 20010, title: '项目验收', start: '2025-02-07', end: '2025-02-09', progress: 0 }
  ]
})
</script>

配置说明

依赖线定义

links: [
  { from: 20001, to: 20002, type: VxeGanttDependencyType.FinishToStart },
  // ...
]
  • from:前置任务 ID。
  • to:后置任务 ID。
  • type:依赖类型,FinishToStart 表示“完成-开始”,即前置任务完成后,后置任务才能开始。
  • 依赖关系是自动同步的基础,必须准确维护。

拖拽移动同步

taskBarMoveConfig: {
  isSyncLinkTask: true
}

开启后,拖拽任务条移动日期时,组件会按照第三节的移动规则自动调整关联任务。

依赖线交互

taskLinkConfig: {
  isHover: true,
  isCurrent: true,
  isDblclickToRemove: true
}
  • isHover:鼠标悬停时高亮依赖线,便于识别。
  • isCurrent:点击依赖线时保持高亮。
  • isDblclickToRemove:双击依赖线可删除,方便调整依赖关系。

任务条样式

barStyle: {
  round: true,
  bgColor: '#fca60b',
  completedBgColor: '#65c16f'
}

自定义任务条圆角、背景色和已完成部分颜色,提升视觉效果。

通过 taskBarMoveConfig.isSyncLinkTask,vxe-gantt 能够实现拖拽任务时自动更新紧前紧后依赖线关联任务的日期,确保项目计划始终符合依赖约束。结合清晰的移动规则和逐层传播机制,开发者可以轻松构建出专业、可靠的甘特图应用。

https://gantt.vxeui.com

posted @ 2026-09-21 09:54  独行者r2  阅读(7)  评论(0)    收藏  举报