Skip to content
D
Documentation

Vue quick start

tutorial
1 min readUpdated

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

bash
npm 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>
Two connected custom job cards appear in the sized canvas with the canvas tools visible.

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

Was this page helpful?

Vue quick start — Grafloria