Skip to main content

Vue Gantt Overview

Vue Gantt is the official Vue wrapper for DHTMLX Gantt. It combines Vue-friendly composition patterns with full access to the underlying Gantt engine.

If you need setup instructions first, start with Quick Start with Vue Gantt.

Mental Model​

Vue Gantt is a wrapper around the DHTMLX Gantt engine. The wrapper gives you a Vue component API, but the underlying engine is still the source of chart behavior and low-level methods.

The wrapper layer does three main jobs:

  • initializes and destroys the Gantt instance with Vue lifecycle
  • syncs selected Vue props into the current Gantt instance
  • exposes wrapper-specific extension points (events, @ready, customLightbox, inlineEditors, composables)

That means you can stay declarative for most integration work and still drop to instance when needed.

Core Capabilities​

The wrapper covers both basic and advanced integration scenarios:

  • Declarative setup with props (config, templates, plugins, theme, locale)
  • Data synchronization for tasks, links, and advanced stores (resources, resourceAssignments, baselines)
  • Event wiring through the events map
  • One-time lifecycle hook through @ready
  • Vue-based customization hooks (customLightbox, inlineEditors, modals)
  • Typed helpers and composables for reusable patterns

Scenario: Basic Wrapper Setup​

Use props for chart configuration and template customization.

<script setup lang="ts">
import { ref } from "vue";
import VueGantt, {
defineGanttConfig,
defineGanttTemplates,
type SerializedLink,
type SerializedTask
} from "@dhtmlx/trial-vue-gantt";
import "@dhtmlx/trial-vue-gantt/dist/vue-gantt.css";

const tasks = ref<SerializedTask[]>([
{
id: 1,
text: "Project",
start_date: new Date(2026, 0, 5),
duration: 5,
open: true,
parent: 0
}
]);
const links = ref<SerializedLink[]>([]);

const config = defineGanttConfig({
scales: [
{ unit: "month", step: 1, format: "%F, %Y" },
{ unit: "day", step: 1, format: "%d %M" }
]
});

const templates = defineGanttTemplates({
task_text: (_start, _end, task) => `#${task.id}: ${task.text}`
});
</script>

<template>
<div style={{height: '520px'}}>
<VueGantt :tasks="tasks" :links="links" :config="config" :templates="templates" />
</div>
</template>

For the full prop list, use Configuration Reference.

Choose A Data Ownership Model​

The wrapper syncs incoming props into the current instance. The main decision is where your app treats data as authoritative.

  • Vue state/store as source of truth: wrapper callbacks (data.save / data.batchSave) update your state, then updated props flow back into the wrapper.
  • Gantt as source of truth: Gantt and backend own the main data lifecycle; Vue props are used less often for live chart state.

When Vue owns the data, prefer SerializedTask[] and SerializedLink[] for reactive state and payload typing.

Sync behavior summary:

  • task/link updates are usually diff-based
  • the wrapper can switch to reset/re-parse for larger changes
  • advanced stores (resources, resourceAssignments, baselines) are synced through their datastores

Use Data Binding and State Management Basics for the tradeoffs and callback contracts.

Handle Events And Startup Logic​

Use the events map for Gantt events and @ready for one-time setup after initialization.

<script setup lang="ts">
import { defineGanttEvents, type GanttStatic } from "@dhtmlx/trial-vue-gantt";

const events = defineGanttEvents({
onTaskCreated: task => {
console.log("task created", task);
return true;
},
onBeforeLightbox: taskId => {
console.log("before lightbox", taskId);
return true;
}
});

const onReady = (instance: GanttStatic) => {
console.log("ready", instance);
};
</script>

<template>
<VueGantt :events="events" @ready="onReady" />
</template>

Use events for interaction behavior. Use @ready for initialization logic that needs a live instance.

Cross The Imperative Boundary​

Use a component ref when you need methods that are not practical to model through props.

<script setup lang="ts">
import { onMounted, ref } from "vue";
import VueGantt, { type VueGanttRef } from "@dhtmlx/trial-vue-gantt";

const ganttRef = ref<VueGanttRef | null>(null);

onMounted(() => {
const gantt = ganttRef.value?.instance;
if (!gantt) return;
gantt.showDate(new Date());
});
</script>

<template>
<VueGantt ref="ganttRef" />
</template>

If you mutate task/link data through instance, keep external state in sync. Otherwise the next prop update can overwrite those changes.

Advanced Extension Points​

Custom lightbox component​

Replace the built-in task form with a Vue component:

<VueGantt :tasks="tasks" :links="links" :customLightbox="CustomLightbox" :data="data" />

Custom inline editors​

Map Gantt inline editor names to Vue components:

<VueGantt :config="config" :inlineEditors="inlineEditors" :data="data" />

Custom delete confirmation flow​

Override delete confirmations with modals:

const modals = {
onBeforeTaskDelete: ({ task, callback }) => {
if (window.confirm(`Delete ${task.text}?`)) callback();
}
};

Task and resource filtering​

Use filter for task filtering and resourceFilter for resource-panel filtering.

Public Sample Scenario Map​

These wrapper features are covered in public sample routes. Run them locally from vue-gantt-examples on GitHub or try the live demo.

  • basic-init: baseline props, config, and templates
  • templates: theme/locale switching, Vue h()-based column templates, grid-side filtering, expand/collapse via instance
  • custom-form: customLightbox
  • custom-edit-view: event-driven external editor flow
  • inline-editors: Vue inline editor mapping
  • auto-scheduling: plugins.auto_scheduling + critical_path with useWorkTime
  • resource-panel: resources + resourceFilter
  • state-management: Pinia store-driven updates
  • export-data: imperative actions with export plugin
Need help?
Got a question about the documentation? Reach out to our technical support team for help and guidance. For custom component solutions, visit the Services page.