Skip to content

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>

在线演示

查看完整在线演示 →

相关链接

基于 MIT 许可证发布