vue 实现拖拽甘特图
实现拖拽甘特图的基本思路
在Vue中实现拖拽甘特图需要结合第三方库或手动实现拖拽逻辑,核心功能包括任务条渲染、时间轴刻度、拖拽交互等。以下是基于vue-ganttastic和手动实现的两种方案。
使用vue-ganttastic库快速实现
vue-ganttastic是一个轻量级甘特图组件库,支持拖拽任务条和调整时间范围。
安装依赖:
npm install vue-ganttastic
基础示例代码:
<template>
<GanttChart :tasks="tasks" @task-updated="handleTaskUpdate" />
</template>
<script>
import { GanttChart } from 'vue-ganttastic';
export default {
components: { GanttChart },
data() {
return {
tasks: [
{ id: 1, name: 'Task 1', start: '2023-01-01', end: '2023-01-05' },
{ id: 2, name: 'Task 2', start: '2023-01-06', end: '2023-01-10' }
]
};
},
methods: {
handleTaskUpdate(updatedTask) {
const index = this.tasks.findIndex(t => t.id === updatedTask.id);
this.tasks.splice(index, 1, updatedTask);
}
}
};
</script>
手动实现拖拽甘特图
若需高度自定义,可通过以下步骤实现:
1. 任务条渲染
使用v-for渲染任务条,绑定样式计算位置:
<template>
<div class="gantt-container">
<div
v-for="task in tasks"
:key="task.id"
class="task-bar"
:style="{
left: calculateLeft(task.start),
width: calculateWidth(task.start, task.end)
}"
draggable="true"
@dragstart="dragStart(task.id)"
@dragend="dragEnd"
></div>
</div>
</template>
2. 拖拽逻辑
记录拖拽起始位置并更新任务数据:
methods: {
dragStart(taskId) {
this.draggedTaskId = taskId;
},
dragEnd(e) {
const newStartDate = this.calculateDateFromPosition(e.clientX);
const task = this.tasks.find(t => t.id === this.draggedTaskId);
task.start = newStartDate;
},
calculateDateFromPosition(x) {
// 根据鼠标位置计算对应日期
}
}
3. 时间轴计算
转换日期为像素位置:

calculateLeft(startDate) {
const start = new Date(this.timeRange.start);
const current = new Date(startDate);
const diffDays = Math.floor((current - start) / (1000 * 60 * 60 * 24));
return `${diffDays * this.dayWidth}px`;
}
关键细节优化
- 时间刻度渲染:使用
<div class="time-scale">横向平铺日期标签 - 拖拽限制:通过
@dragover.prevent防止默认行为,检查边界条件 - 性能优化:对大型数据集使用虚拟滚动(如
vue-virtual-scroller)
完整实现可能需要结合resize监听、时间单位切换(日/周/月)等功能,复杂场景建议选择成熟库如dhtmlxGantt或frappe-gantt。






