Render a typed Vue diagram, add slot-defined nodes, size its host, and keep the mounted instance available for imperative actions.
What you build
GrafloriaFlow is the Vue surface over Grafloria's shared headless engine. The model is data, while the engine handles diagram behavior such as fitting the view. In this tutorial, the canvas shows two connected cards, a minimap and zoom controls, and a Fit view button.
Prerequisites
- Vue 3.4 or later
- A Vue application using a bundler such as Vite
The Vue package declares Vue 3.4+, @grafloria/engine 0.3+, @grafloria/renderer 0.4.16+, and @grafloria/element 0.4.3+ as peer dependencies.
1. Install the packages
bashnpm install @grafloria/vue @grafloria/engine @grafloria/renderer @grafloria/element vue
2. Mount a typed flow
Replace your App.vue with this component. NodeSpec describes the boxes and EdgeSpec describes the connection between them.
vue<script setup lang="ts"> import { ref } from 'vue'; import { GrafloriaFlow } from '@grafloria/vue'; import type { DiagramInstance, EdgeSpec, NodeSpec } from '@grafloria/vue'; const nodes = ref<NodeSpec[]>([ { id: 'build', type: 'job', position: { x: 60, y: 80 }, size: { width: 220, height: 100 }, data: { title: 'Build', owner: 'CI' }, }, { id: 'deploy', type: 'job', position: { x: 400, y: 80 }, size: { width: 220, height: 100 }, data: { title: 'Deploy', owner: 'CD' }, }, ]); const edges = ref<EdgeSpec[]>([ { id: 'build-to-deploy', source: 'build', target: 'deploy' }, ]); let instance: DiagramInstance | null = null; function onInit(api: DiagramInstance): void { instance = api; } function fitDiagram(): void { instance?.fitView(24); } </script> <template> <div class="editor"> <button type="button" @click="fitDiagram">Fit view</button> <GrafloriaFlow v-model:nodes="nodes" v-model:edges="edges" :plugins="true" style="width: 100%; height: 420px" @init="onInit" > <template #node-job="{ data }"> <div class="job-card"> <strong>{{ data.title }}</strong> <span>owner: {{ data.owner }}</span> </div> </template> </GrafloriaFlow> </div> </template> <style scoped> .editor { width: 100%; } button { margin-bottom: 8px; } .job-card { display: flex; height: 100%; box-sizing: border-box; flex-direction: column; justify-content: center; gap: 6px; padding: 12px 16px; border: 1.5px solid #94a5f0; border-radius: 12px; background: #fff; } .job-card span { color: #5a6478; font-size: 12px; } </style>
The style gives the canvas both a width and a resolved height. The two job nodes render through #node-job, and the slot receives the node's data, so the canvas shows Build and Deploy as cards rather than stock rectangles. v-model:nodes and v-model:edges keep the Vue refs synchronized when the user edits the diagram. plugins="true" mounts the shipped minimap, zoom/fit controls, and background grid.
3. Use the instance
The @init event supplies the live DiagramInstance after the diagram mounts. The sample stores it and calls fitView(24) from the button; the view frames the diagram with 24 units of padding. The same instance exposes the model through getModel() and the behavior engine through getEngine() when a later feature needs those layers.
Do not call fitView() during teardown. The component disposes its instance when Vue unmounts it.
Where next
- Create custom nodes for slot renderers and node behavior.
- State, events, and undo for the instance event surface and engine history.
- Auto-layout a diagram for the declarative
layoutprop. - Open the Vue demo gallery to run the Vue examples.
Was this page helpful?