Vue Flow Documentation

repository·master·Indexed 27 days ago

https://github.com/bcakmakoglu/vue-flow

A highly customizable flowchart component for Vue 3 featuring built-in support for zooming, panning, element dragging, and selection. The library includes a core package (@vue-flow/core) and several specialized components such as Background, Controls, MiniMap, NodeResizer, and NodeToolbar. It is designed for fast, reactive diagrams using nodes and edges, and is exclusively compatible with Vue 3.

Tokens
33.3K
Snippets
100
Records
170
Agent score
91%

What's inside Vue Flow

  1. Introduction to Vue Flow

    master

    Vue Flow is a library for creating interactive flowcharts and graphs in Vue.js. It provides a foundation for building dynamic diagrams, editors, and graphic representations.

    Key capabilities include:

    • Built-in Interactivity: Supports element dragging, zooming, panning, and selection out of the box.
    • Extensibility: Allows for the creation of custom nodes, edges, and connection lines.
    • Reactive Performance: Uses Vue's reactivity system to ensure efficient re-renders of only necessary elements.
    • Composability: Provides built-in graph helpers and state composable functions for managing complex graph logic.
    • TypeScript Support: Fully written in TypeScript for improved developer reliability and type safety.
  2. Listen to events on the VueFlow component

    master

    You can react to flow changes by listening to events directly on the <VueFlow> component using Vue's @ directive. Common events include @node-click and @edge-click.

    <script setup>
    import { ref } from 'vue';  
    import { VueFlow } from '@vue-flow/core';
    
    const nodes = ref([/* ... */]);
    const edges = ref([/* ... */]);
    
    // Node click event handler
    function onNodeClick({ event, node }) {
      console.log('Node clicked:', node, event);
    }
    
    // Edge click event handler
    function onEdgeClick({ event, edge }) {
      console.log('Edge clicked:', edge, event);
    }
    </script>
    
    <template>
      <VueFlow :nodes="nodes" :edges="edges" @node-click="onNodeClick" @edge-click="onEdgeClick"></VueFlow>
    </template>
  3. Use PathFindingEdge to create edges that avoid nodes

    master

    The PathFindingEdge is a custom edge type designed to avoid crossing nodes.

    ⚠️ DEPRECATED: This package is deprecated and will be removed in the next major release.

    To implement it:

    1. Import PathFindingEdge from @vue-flow/pathfinding-edge.
    2. Use the useVueFlow hook from @vue-flow/core to access getNodes.
    3. Register the edge using the #edge-pathfinding slot in the VueFlow component.
    4. Pass the getNodes function to the :nodes prop of PathFindingEdge.
    5. Set the type of your edge element to 'pathfinding' in your elements array.
    <script setup>
    import { ref } from 'vue'
    import { VueFlow, useVueFlow } from '@vue-flow/core'
    import { PathFindingEdge } from '@vue-flow/pathfinding-edge'
    
    const elements = ref([
      {
        id: 'e12',
        source: '1',
        target: '2',
        label: 'Smart Edge',
        style: { stroke: 'red' },
        // assign pathfinding edge type
        type: 'pathfinding'
      },
      {
        id: '1',
        label: 'Node 1',
        position: { x: 430, y: 0 },
      },
      {
        id: '2',
        label: 'Node 2',
        position: { x: 230, y: 90 },
      },
    ]
    )
    
    // create a new context so we can fetch nodes
    const { getNodes } = useVueFlow()
    </script>
    
    <template>
      <div style="height: 300px">
        <VueFlow v-model="elements">
          <template #edge-pathfinding="props">
            <PathFindingEdge v-bind="props" :nodes="getNodes" />
          </template>
        </VueFlow>
      </div>
    </template>
  4. Configure Vue Flow styles

    master

    To ensure Vue Flow displays correctly, you must import the core styles. You can also optionally import the default theme.

    /* these are necessary styles for vue flow */
    @import '@vue-flow/core/dist/style.css';
    
    /* this contains the default theme, these are optional styles */
    @import '@vue-flow/core/dist/theme-default.css';
  5. Create User-Defined Edges using Template Slots

    master

    You can define custom edge types by using template slots within the VueFlow component. When an edge has a type property (e.g., type: 'custom'), Vue Flow looks for a slot named #edge-[type] (e.g., #edge-custom). You can pass the edge properties to your custom component using v-bind="props".

    <script setup>
    import { ref } from 'vue'
    import { VueFlow } from '@vue-flow/core'
    import CustomEdge from './CustomEdge.vue'
    
    const nodes = ref([
      { id: '1', position: { x: 50, y: 50 }, data: { label: 'Node 1' } },
      { id: '2', position: { x: 50, y: 250 }, data: { label: 'Node 2' } },
    ])
    
    const edges = ref([
      { id: 'e1->2', type: 'custom', source: '1', target: '2' },
    ])
    </script>
    
    <template>
      <VueFlow :nodes="nodes" :edges="edges">
        <template #edge-custom="props">
          <CustomEdge v-bind="props" />
        </template>
      </VueFlow>
    </template>
  6. Access Viewport Functions via useVueFlow or onPaneReady

    master

    Viewport functions can be accessed in two ways:

    1. Using the useVueFlow composable: Best for <script setup> environments.
    2. Using the onPaneReady event: The VueFlowStore instance is provided as an argument to the onPaneReady event handler.

    This instance allows you to manipulate the viewport (zoom, pan) and access flow elements.

    <script setup>
    import { VueFlow, useVueFlow } from '@vue-flow/core'
    
    const { onPaneReady } = useVueFlow()
    
    // event handler
    onPaneReady((instance) => instance.fitView())
    </script>
  7. Add edges to the graph

    master

    Edges connect nodes and require a unique id, a source node ID, and a target node ID. You can add edges by passing them to the :edges prop of the VueFlow component. For more complex interactions or when working outside the component (e.g., in a Sidebar), use the addEdges action from the useVueFlow composable.

    <script setup>
    import { ref } from 'vue'
    import { VueFlow, useVueFlow } from '@vue-flow/core'
    
    const nodes = ref([
      { id: '1', position: { x: 50, y: 50 }, data: { label: 'Node 1' } },
      { id: '2', position: { x: 50, y: 250 }, data: { label: 'Node 2' } }
    ])
    
    const { addEdges } = useVueFlow()
    
    function addNewEdge() {
      addEdges([
        {
          id: 'e1-2',
          source: '1',
          target: '2',
          // If a node has multiple handles of the same type, specify the handle ID
          sourceHandle: null,
          targetHandle: null,
        }
      ])
    }
    </script>
    
    <template>
      <VueFlow :nodes="nodes" />
    </template>
  8. Create User-Defined Edges using the edgeTypes object

    master

    Alternatively, you can define custom edge types by passing an edgeTypes object to the VueFlow component.

    Important: Use Vue's markRaw function when defining the edgeTypes object to prevent Vue from converting your components into reactive objects, which avoids console warnings.

    <script setup>
    import { ref, markRaw } from 'vue'
    import { VueFlow } from '@vue-flow/core'
    import CustomEdge from './CustomEdge.vue'
    
    const edgeTypes = {
      custom: markRaw(CustomEdge),
    }
    
    const nodes = ref([
      { id: '1', position: { x: 50, y: 50 }, data: { label: 'Node 1' } },
      { id: '2', position: { x: 50, y: 250 }, data: { label: 'Node 2' } },
    ])
    
    const edges = ref([
      { id: 'e1->2', type: 'custom', source: '1', target: '2' },
    ])
    </script>
    
    <template>
      <VueFlow :nodes="nodes" :edges="edges" :edgeTypes="edgeTypes" />
    </template>
  9. Initialize a Vue Flow store for external components

    master

    To avoid prop drilling when using external components (like a Sidebar) that need to interact with the flow, initialize a Vue Flow store instance in a parent component before the external component is initialized. This makes the instance available via injection throughout the component tree.

    Note: If you have multiple store instances in the same context, you must provide a unique id to each to ensure you access the correct instance. Otherwise, useVueFlow will inject the first instance it finds (usually the last one injected).

    <!-- Container.vue -->
    <script>
    import { useVueFlow  } from '@vue-flow/core'
    
    // initialize a store instance in this context, so it is available when calling inject(VueFlow)
    useVueFlow()
    </script>