甘特图vue实现
甘特图 Vue 实现方法
使用开源库 vue-ganttastic
安装依赖:
npm install vue-ganttastic
基础实现代码:
<template>
<GanttChart
:tasks="tasks"
:options="options"
/>
</template>
<script>
import { GanttChart } from 'vue-ganttastic'
export default {
components: {
GanttChart
},
data() {
return {
tasks: [
{
id: 1,
name: '任务1',
start: '2023-01-01',
end: '2023-01-05'
},
{
id: 2,
name: '任务2',
start: '2023-01-06',
end: '2023-01-10'
}
],
options: {
viewMode: 'day',
style: {
'bar-color': '#4682B4',
'bar-radius': '4px'
}
}
}
}
}
</script>
自定义实现方案
基础HTML结构:
<template>
<div class="gantt-container">
<div class="gantt-header">
<div v-for="day in days" :key="day" class="gantt-header-day">
{{ day }}
</div>
</div>
<div class="gantt-body">
<div v-for="task in tasks" :key="task.id" class="gantt-task">
<div class="task-name">{{ task.name }}</div>
<div class="task-bar-container">
<div
class="task-bar"
:style="{
width: calculateWidth(task),
marginLeft: calculateMargin(task)
}"
></div>
</div>
</div>
</div>
</div>
</template>
计算逻辑:
methods: {
calculateWidth(task) {
const start = new Date(task.start)
const end = new Date(task.end)
const diff = (end - start) / (1000 * 60 * 60 * 24)
return `${diff * 30}px`
},
calculateMargin(task) {
const start = new Date(task.start)
const projectStart = new Date(this.projectStart)
const diff = (start - projectStart) / (1000 * 60 * 60 * 24)
return `${diff * 30}px`
}
}
进阶功能实现
时间轴缩放控制:
data() {
return {
zoomLevel: 1,
zoomOptions: [0.5, 1, 2, 3]
}
},
methods: {
changeZoom(level) {
this.zoomLevel = level
}
}
任务拖拽功能:
mounted() {
interact('.task-bar')
.draggable({
onmove: this.handleDrag
})
},
methods: {
handleDrag(event) {
const target = event.target
const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx
target.style.left = `${x}px`
target.setAttribute('data-x', x)
}
}
样式优化建议
CSS样式示例:
.gantt-container {
width: 100%;
overflow-x: auto;
}
.gantt-header {
display: flex;
border-bottom: 1px solid #ddd;
}
.gantt-header-day {
min-width: 30px;
text-align: center;
padding: 5px;
}
.task-bar {
height: 20px;
background-color: #4CAF50;
position: relative;
border-radius: 3px;
}
数据动态加载
API集成示例:
async created() {
try {
const response = await axios.get('/api/tasks')
this.tasks = response.data
} catch (error) {
console.error('Error fetching tasks:', error)
}
}






