Vue 使用示例
基础用法
vue
<template>
<div style="height: 500px">
<GanttChart
:tasks="tasks"
view-mode="week"
/>
</div>
</template>
<script setup lang="ts">
import { GanttChart } from "@agions/gantt-flow/vue"
import "@agions/gantt-flow/style"
const tasks = [
{
id: "1",
name: "需求分析",
start: "2023-03-01",
end: "2023-03-05",
progress: 100,
},
{
id: "2",
name: "系统设计",
start: "2023-03-06",
end: "2023-03-10",
progress: 80,
},
{
id: "3",
name: "编码实现",
start: "2023-03-11",
end: "2023-03-20",
progress: 50,
},
]
</script>带依赖关系
vue
<template>
<div style="height: 500px">
<GanttChart
:tasks="tasks"
:dependencies="dependencies"
view-mode="week"
@task-click="onTaskClick"
/>
</div>
</template>
<script setup lang="ts">
import { GanttChart } from "@agions/gantt-flow/vue"
import "@agions/gantt-flow/style"
import type { Task, Dependency } from "@agions/gantt-flow"
const tasks: Task[] = [
{ id: "1", name: "需求分析", start: "2023-03-01", end: "2023-03-05" },
{ id: "2", name: "系统设计", start: "2023-03-06", end: "2023-03-08" },
{ id: "3", name: "详细设计", start: "2023-03-09", end: "2023-03-12" },
{ id: "4", name: "编码实现", start: "2023-03-13", end: "2023-03-20" },
{ id: "5", name: "测试验收", start: "2023-03-21", end: "2023-03-25" },
]
const dependencies: Dependency[] = [
{ fromId: "1", toId: "2", type: "finish_to_start" },
{ fromId: "2", toId: "3", type: "finish_to_start" },
{ fromId: "3", toId: "4", type: "finish_to_start" },
{ fromId: "4", toId: "5", type: "finish_to_start" },
]
const onTaskClick = (task: Task) => {
console.log("任务点击:", task.name)
}
</script>使用 Ref 调用方法
vue
<template>
<div>
<div class="toolbar">
<button @click="handleExport">导出 PNG</button>
<button @click="setMonthView">月视图</button>
<button @click="setWeekView">周视图</button>
<button @click="fitScreen">适应屏幕</button>
</div>
<div style="height: 500px">
<GanttChart ref="ganttChart" :tasks="tasks" />
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue"
import { GanttChart } from "@agions/gantt-flow/vue"
import "@agions/gantt-flow/style"
const ganttChart = ref<InstanceType<typeof GanttChart> | null>(null)
const tasks = [
{ id: "1", name: "需求分析", start: "2023-03-01", end: "2023-03-05" },
{ id: "2", name: "系统设计", start: "2023-03-06", end: "2023-03-10" },
]
const handleExport = async () => {
const dataUrl = await ganttChart.value?.exportAsPNG()
if (dataUrl) {
const link = document.createElement('a')
link.href = dataUrl
link.download = 'gantt.png'
link.click()
}
}
const setMonthView = () => {
ganttChart.value?.setViewMode('month')
}
const setWeekView = () => {
ganttChart.value?.setViewMode('week')
}
const fitScreen = () => {
ganttChart.value?.fitToScreen()
}
</script>事件监听
vue
<template>
<div style="height: 500px">
<GanttChart
:tasks="tasks"
@task-click="onTaskClick"
@task-drag="onTaskDrag"
@view-change="onViewChange"
@task-progress="onProgressChange"
/>
</div>
</template>
<script setup lang="ts">
import { GanttChart } from "@agions/gantt-flow/vue"
import "@agions/gantt-flow/style"
import type { Task, ViewMode } from "@agions/gantt-flow"
const tasks: Task[] = [
{ id: "1", name: "需求分析", start: "2023-03-01", end: "2023-03-05" },
{ id: "2", name: "系统设计", start: "2023-03-06", end: "2023-03-10" },
]
const onTaskClick = (task: Task) => {
console.log("任务点击:", task)
}
const onTaskDrag = (
task: Task,
event: MouseEvent,
newStart: Date,
newEnd: Date
) => {
console.log("拖拽:", task.name, newStart, newEnd)
}
const onViewChange = (mode: ViewMode) => {
console.log("视图切换:", mode)
}
const onProgressChange = (task: Task, progress: number) => {
console.log("进度变化:", task.name, progress)
}
</script>主题切换
vue
<template>
<div>
<button @click="toggleTheme">
{{ isDark ? '切换到亮色' : '切换到暗色' }}
</button>
<div style="height: 500px">
<GanttChart
ref="ganttChart"
:tasks="tasks"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue"
import { GanttChart } from "@agions/gantt-flow/vue"
import "@agions/gantt-flow/style"
const isDark = ref(false)
const ganttChart = ref<InstanceType<typeof GanttChart> | null>(null)
const tasks = [
{ id: "1", name: "需求分析", start: "2023-03-01", end: "2023-03-05" },
{ id: "2", name: "系统设计", start: "2023-03-06", end: "2023-03-10" },
]
const toggleTheme = () => {
isDark.value = !isDark.value
ganttChart.value?.setTheme(isDark.value ? 'dark' : 'light')
}
</script>响应式配置
vue
<template>
<div style="height: 500px">
<GanttChart
:tasks="tasks"
:column-width="columnWidth"
:row-height="rowHeight"
:virtual-scrolling="tasks.length > 100"
/>
</div>
</template>
<script setup lang="ts">
import { computed } from "vue"
import { useWindowSize } from "@vueuse/core"
import { GanttChart } from "@agions/gantt-flow/vue"
import "@agions/gantt-flow/style"
const { width } = useWindowSize()
const columnWidth = computed(() => {
return width.value < 768 ? 40 : 60
})
const rowHeight = computed(() => {
return width.value < 768 ? 36 : 44
})
const tasks = [
{ id: "1", name: "需求分析", start: "2023-03-01", end: "2023-03-05" },
{ id: "2", name: "系统设计", start: "2023-03-06", end: "2023-03-10" },
]
</script>完整项目示例
vue
<template>
<div class="project-gantt">
<!-- 工具栏 -->
<div class="toolbar">
<h2>📊 项目甘特图</h2>
<div class="actions">
<select v-model="viewMode" @change="onViewChange">
<option value="day">日</option>
<option value="week">周</option>
<option value="month">月</option>
<option value="quarter">季度</option>
</select>
<button @click="handleFitScreen">适应屏幕</button>
<button @click="handleExport('png')">导出 PNG</button>
<button @click="handleExport('pdf')">导出 PDF</button>
<button @click="toggleTheme">
{{ theme === 'dark' ? '☀️ 亮色' : '🌙 暗色' }}
</button>
</div>
</div>
<!-- 甘特图 -->
<div class="gantt-container" :style="{ height: ganttHeight }">
<GanttChart
ref="ganttChart"
:tasks="tasks"
:view-mode="viewMode"
:options="{ theme }"
@task-click="onTaskClick"
@task-drag="onTaskDrag"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from "vue"
import { GanttChart } from "@agions/gantt-flow/vue"
import "@agions/gantt-flow/style"
import type { Task, ViewMode } from "@agions/gantt-flow"
const ganttChart = ref<InstanceType<typeof GanttChart> | null>(null)
const tasks = ref<Task[]>([
{ id: "1", name: "需求分析", start: "2024-01-01", end: "2024-01-05", progress: 100 },
{ id: "2", name: "系统设计", start: "2024-01-06", end: "2024-01-10", progress: 80 },
{ id: "3", name: "编码实现", start: "2024-01-11", end: "2024-01-20", progress: 30 },
{ id: "4", name: "测试验收", start: "2024-01-21", end: "2024-01-25", progress: 0 },
])
const viewMode = ref<ViewMode>("week")
const theme = ref<"light" | "dark">("light")
const ganttHeight = computed(() => {
return "calc(100vh - 120px)"
})
const onTaskClick = (task: Task) => {
console.log("任务点击:", task)
}
const onTaskDrag = (task: Task, e: MouseEvent, newStart: Date, newEnd: Date) => {
tasks.value = tasks.value.map(t =>
t.id === task.id ? { ...t, start: newStart, end: newEnd } : t
)
}
const onViewChange = () => {
ganttChart.value?.setViewMode(viewMode.value)
}
const handleFitScreen = () => {
ganttChart.value?.fitToScreen()
}
const handleExport = async (format: "png" | "pdf") => {
let data
if (format === "png") {
data = await ganttChart.value?.exportAsPNG()
} else {
const blob = await ganttChart.value?.exportAsPDF()
data = blob ? URL.createObjectURL(blob) : null
}
if (data) {
const link = document.createElement("a")
link.href = data
link.download = `gantt.${format}`
link.click()
}
}
const toggleTheme = () => {
theme.value = theme.value === "light" ? "dark" : "light"
ganttChart.value?.setTheme(theme.value)
}
</script>
<style scoped>
.project-gantt {
padding: 20px;
}
.toolbar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.toolbar h2 {
margin: 0;
}
.actions {
display: flex;
gap: 8px;
}
.gantt-container {
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
</style>在线演示
相关链接
- React 使用示例 - React 版本示例
- 完整示例 - 更多功能展示
- API 参考 - 组件属性