vue甘特图vxe-gantt如何实现拖拽任务条时如有已关联依赖线,同时更新依赖任务的日期的方式
当任务关联前置任务或后置任务依赖线时,拖拽该任务时同步更新对应的起始日期和结束日期,可以通过 task-bar-drag-config.isSyncLinkTask 来启用
基础代码
简单实现同步移动任务
<template><div><vxe-ganttv-bind="ganttOptions"></vxe-gantt></div></template><scriptsetup>import{reactive}from'vue'import{VxeGanttDependencyType}from'vxe-gantt'importXEUtilsfrom'xe-utils'constganttOptions=reactive({border:true,height:600,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:10001,to:10002,type:VxeGanttDependencyType.FinishToFinish},{from:10004,to:10005,type:VxeGanttDependencyType.StartToStart},{from:10005,to:10006,type:VxeGanttDependencyType.FinishToStart},{from:10013,to:10012,type:VxeGanttDependencyType.StartToFinish}],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:10001,title:'任务1',start:'2024-03-01',end:'2024-03-04',progress:3},{id:10002,title:'任务2',start:'2024-03-03',end:'2024-03-08',progress:10},{id:10003,title:'任务3',start:'2024-03-03',end:'2024-03-11',progress:90},{id:10004,title:'任务4',start:'2024-03-05',end:'2024-03-11',progress:15},{id:10005,title:'任务5',start:'2024-03-08',end:'2024-03-15',progress:100},{id:10006,title:'任务6',start:'2024-03-10',end:'2024-03-21',progress:5},{id:10007,title:'任务7',start:'2024-03-15',end:'2024-03-24',progress:70},{id:10008,title:'任务8',start:'2024-03-05',end:'2024-03-15',progress:50},{id:10009,title:'任务9',start:'2024-03-19',end:'2024-03-20',progress:5},{id:10010,title:'任务10',start:'2024-03-12',end:'2024-03-20',progress:10},{id:10011,title:'任务11',start:'2024-03-01',end:'2024-03-08',progress:90},{id:10012,title:'任务12',start:'2024-03-03',end:'2024-03-06',progress:60},{id:10013,title:'任务13',start:'2024-03-02',end:'2024-03-05',progress:50},{id:10014,title:'任务14',start:'2024-03-04',end:'2024-03-15',progress:0},{id:10015,title:'任务15',start:'2024-03-01',end:'2024-03-05',progress:30}]})</script>还可以实现更复杂的逻辑
<template><div><vxe-ganttref="ganttRef"v-bind="ganttOptions"@task-bar-drag-end="onTaskDragEnd"></vxe-gantt></div></template><scriptsetup>import{reactive,ref}from'vue'import{VxeGanttDependencyType}from'vxe-gantt'importXEUtilsfrom'xe-utils'constganttRef=ref(null)constganttOptions=reactive({// ...(保持原有配置)taskBarMoveConfig:{// 自定义拖拽结束时任务日期被赋值的方法asyncmoveSetMethod({row,startValue,endValue,offsetSize,linkInfo}){const$gantt=ganttRef.valueif(!$gantt){return}const{allLinks,allRows}=linkInfo console.log('关联连接线:',allLinks,'对应行:',allRows)row.start=startValue row.end=endValue// 实现拖拽任务后,关联任务自动同步更新日期allRows.forEach(currRow=>{if(row!==currRow){currRow.start=XEUtils.toDateString(XEUtils.getWhatDay(currRow.start,offsetSize),'yyyy-MM-dd')currRow.end=XEUtils.toDateString(XEUtils.getWhatDay(currRow.end,offsetSize),'yyyy-MM-dd')}})// 获取所有关联线// allLinks.forEach((linkItem, i) => {// // 取出连接线起始对应的行// const linkFromRow = $gantt.getRowById(linkItem.from)// // 取出连接线结束对应的行// const linkToRow = $gantt.getRowById(linkItem.to)// // 判断线类型// switch (linkItem.type) {// case VxeGanttDependencyType.FinishToStart: {// // 实现拖拽任务后,关联任务自动同步更新日期// if (linkFromRow) {// linkFromRow.start = XEUtils.toDateString(XEUtils.getWhatDay(linkFromRow.start, offsetSize), 'yyyy-MM-dd')// linkFromRow.end = XEUtils.toDateString(XEUtils.getWhatDay(linkFromRow.end, offsetSize), 'yyyy-MM-dd')// }// break// }// case VxeGanttDependencyType.StartToFinish : {// // 实现拖拽任务后,关联任务自动同步更新日期// if (linkFromRow) {// linkFromRow.start = XEUtils.toDateString(XEUtils.getWhatDay(linkFromRow.start, offsetSize), 'yyyy-MM-dd')// linkFromRow.end = XEUtils.toDateString(XEUtils.getWhatDay(linkFromRow.end, offsetSize), 'yyyy-MM-dd')// }// break// }// case VxeGanttDependencyType.StartToStart : {// // 实现拖拽任务后,关联任务自动同步更新日期// if (linkFromRow) {// linkFromRow.start = XEUtils.toDateString(XEUtils.getWhatDay(linkFromRow.start, offsetSize), 'yyyy-MM-dd')// linkFromRow.end = XEUtils.toDateString(XEUtils.getWhatDay(linkFromRow.end, offsetSize), 'yyyy-MM-dd')// }// break// }// case VxeGanttDependencyType.FinishToFinish : {// // 实现拖拽任务后,关联任务自动同步更新日期// if (linkFromRow) {// linkFromRow.start = XEUtils.toDateString(XEUtils.getWhatDay(linkFromRow.start, offsetSize), 'yyyy-MM-dd')// linkFromRow.end = XEUtils.toDateString(XEUtils.getWhatDay(linkFromRow.end, offsetSize), 'yyyy-MM-dd')// }// break// }// }// })}},// ...(保持原有数据配置)})// 监听拖拽事件,执行其他业务逻辑(如保存到后端)constonTaskDragEnd=({row,startValue,endValue})=>{// 可以在这里保存更新后的任务数据,或者执行其他业务逻辑console.log('任务拖拽完成',{row,startValue,endValue})// 可选:触发数据更新到后端// updateTaskToBackend(row)}</script>依赖类型说明
| 依赖类型 | 原逻辑缺陷 | 优化后逻辑 |
|---|---|---|
| FinishToStart | 前置任务结束日期推迟,后置任务应该整体推迟?❌ 应该是后置任务的开始日期=前置任务的结束日期 | 仅更新后置任务的开始日期,保持持续时间不变 |
| StartToStart | 同时开始的任务,拖拽一个不应该导致另一个结束日期整体偏移 | 保持两个任务的结束日期相对不变,仅调整开始日期 |
| FinishToFinish | 两个任务同时结束,拖拽一个不应该影响另一个的开始日期 | 保持两个任务的开始日期相对不变,仅调整结束日期 |
| StartToFinish | 前置任务开始日期影响后置任务完成日期 | 根据依赖关系的具体约束来精确更新 |
https://gantt.vxeui.com