当前位置:首页 > VUE

vue 实现拖拽甘特图

2026-02-11 03:14:56VUE

实现拖拽甘特图的核心步骤

使用 Vue 实现拖拽甘特图需要结合第三方库或自定义逻辑,核心功能包括任务条渲染、时间轴刻度、拖拽交互等。以下是具体实现方法:

选择基础库

推荐使用 vue-draggablevuedraggable 处理拖拽逻辑,配合 SVG 或 Canvas 渲染甘特图。若需完整功能,可直接集成开源库如 dhtmlx-ganttvue-gantt-elastic

安装基础依赖:

npm install vuedraggable @svgdotjs/svg.js

数据结构设计

甘特图任务数据通常为嵌套结构,包含任务名称、开始/结束时间、层级关系等:

tasks: [
  {
    id: 1,
    name: "任务A",
    start: "2023-01-01",
    end: "2023-01-05",
    progress: 80,
    children: [
      { id: 2, name: "子任务A1", start: "2023-01-01", end: "2023-01-03" }
    ]
  }
]

时间轴渲染

使用 SVG 或 CSS Grid 绘制水平时间轴,动态计算刻度位置:

vue 实现拖拽甘特图

<div class="gantt-header">
  <div 
    v-for="day in timeRange" 
    :key="day.date" 
    :style="{ width: `${dayWidth}px` }"
  >
    {{ day.label }}
  </div>
</div>

计算时间范围的逻辑:

computed: {
  timeRange() {
    const range = [];
    let current = new Date(this.startDate);
    while (current <= new Date(this.endDate)) {
      range.push({
        date: current.toISOString(),
        label: current.getDate()
      });
      current.setDate(current.getDate() + 1);
    }
    return range;
  }
}

任务条拖拽实现

通过 vuedraggable 实现任务条的拖拽和位置更新:

<draggable 
  v-model="tasks"
  group="gantt"
  @end="onDragEnd"
>
  <div 
    v-for="task in tasks" 
    :key="task.id"
    class="gantt-task"
    :style="{
      left: `${getTaskPosition(task.start)}px`,
      width: `${getTaskDuration(task.start, task.end)}px`
    }"
  >
    {{ task.name }}
  </div>
</draggable>

拖拽结束后的回调处理:

vue 实现拖拽甘特图

methods: {
  onDragEnd(evt) {
    const movedTask = this.tasks[evt.newIndex];
    const newStart = this.calculateDateFromPosition(evt.item.style.left);
    // 更新任务时间
    movedTask.start = newStart;
    movedTask.end = this.calculateEndDate(newStart, movedTask.duration);
  }
}

动态调整任务时长

添加拖拽手柄允许调整任务条长度:

<div class="gantt-task">
  <div class="task-content">{{ task.name }}</div>
  <div 
    class="resize-handle"
    @mousedown="startResize(task)"
  ></div>
</div>

调整逻辑示例:

startResize(task, evt) {
  window.addEventListener('mousemove', this.handleResize);
  window.addEventListener('mouseup', this.stopResize);
  this.resizingTask = task;
},

handleResize(evt) {
  if (!this.resizingTask) return;
  const newWidth = evt.clientX - this.$el.getBoundingClientRect().left;
  this.resizingTask.end = this.calculateDateFromPosition(newWidth);
}

进阶优化方向

  1. 性能优化:虚拟滚动处理大量任务
  2. 依赖关系:使用箭头连接关联任务
  3. 缩放控制:添加时间单位切换(天/周/月)
  4. 状态持久化:保存拖拽后的任务数据到后端

完整实现可参考开源项目:

标签: 拖拽甘特图
分享给朋友:

相关文章

vue拖拽容器实现

vue拖拽容器实现

Vue 拖拽容器实现方法 在 Vue 中实现拖拽容器功能可以通过原生 HTML5 的拖放 API 或第三方库如 vuedraggable 来实现。以下是两种方法的详细说明。 使用 HTML5 拖放…

vue实现拖拽放置

vue实现拖拽放置

Vue 实现拖拽放置功能 拖拽放置功能可以通过 Vue 的指令或第三方库实现。以下是两种常见的方法: 使用 HTML5 原生拖拽 API HTML5 提供了原生的拖拽 API,可以通过 dragga…

vue 实现可拖拽

vue 实现可拖拽

实现拖拽功能的基本思路 在Vue中实现拖拽功能可以通过HTML5的Drag and Drop API或第三方库如vuedraggable来完成。以下是两种常见方法的详细说明。 使用HTML5原生拖拽…

vue实现拖拽上传

vue实现拖拽上传

Vue 拖拽上传实现方法 使用 HTML5 原生拖拽 API 在 Vue 中可以通过监听原生拖拽事件实现基础功能: <template> <div class="dr…

div拖拽实现vue

div拖拽实现vue

实现 Vue 中的 div 拖拽功能 在 Vue 中实现 div 拖拽功能可以通过原生 HTML5 的拖拽 API 或第三方库如 vuedraggable 完成。以下是两种方法的详细实现: 使用 H…

vue实现列拖拽

vue实现列拖拽

Vue 实现列拖拽功能 使用原生 HTML5 拖放 API 在 Vue 中可以通过原生 HTML5 的拖放 API 实现列拖拽功能。需要处理 draggable、dragstart、dragover…