Skip to content

运行示例窗口

示例窗口提示

  • 红色按钮恢复原始状态
  • 黄色按钮缩小/恢复
  • 绿色按钮开启画中画
  • 可通过标题栏拖动窗口。
  • 可拖动窗口右下角改变窗口大小。

窗口

开始

安装

bash
npm add @vue-flow/core
bash
pnpm add @vue-flow/core
bash
yarn add @vue-flow/core

示例

  1. 在 Vue Flow 中,应用程序结构由节点和边组成,所有这些都被归类为元素。
  2. 每个元素都需要一个唯一的 ID。
  3. 节点还需要一个 XY 位置,而边需要源和目标,两者都由节点 ID 表示。
vue
<script setup>
import { VueFlow } from '@vue-flow/core';
import { elementNodes, elementEdges } from './js/elements.js';
import SpecialNode from './components/SpecialNode.vue';
import SpecialEdge from './components/SpecialEdge.vue';
</script>

<template>
    <VueFlow :nodes="elementNodes" :edges="elementEdges">
            <template #node-special="specialNodeProps">
                <special-node v-bind="specialNodeProps" />
            </template>
            <template #edge-special="specialEdgeProps">
                <special-edge v-bind="specialEdgeProps" />
            </template>
    </VueFlow>
</template>

<style>
@import '@vue-flow/core/dist/style.css';
@import '@vue-flow/core/dist/theme-default.css';
</style>
js
import { ref } from 'vue'

const elementNodes.value = [
    // 节点
    { id: '1', type: 'input', label: 'Node 1', position: { x: 250, y: 5 } },
    { id: '2', label: 'Node 2', position: { x: 100, y: 100 }, },
    { id: '3', type: 'output', label: 'Node 3', position: { x: 400, y: 200 } },
    {
        id: '4',
        type: 'special',
        label: 'Node 4',
        position: { x: 180, y: 200 },
        data: {
            hello: 'world',
        },
    },
]
const elementEdges.value = [
    // 边
    { id: 'e1-3', source: '1', target: '3' },
    { id: 'e1-2', source: '1', target: '2', animated: true },
    {
        id: 'e1-4',
        type: 'special',
        source: '1',
        target: '4',
        data: {
            hello: 'world',
        }
    },
]

export { elements }
vue
<template>
    <div style="background-color: pink;padding: 10px;border-radius: 5px;">
        <div>{{ attrs.label }}</div>
        <div>{{ attrs.data }}</div>

    </div>
</template>

<script setup>
import { useAttrs } from 'vue';
const attrs = useAttrs();
</script>
vue
<template>
    <path :d="`M${attrs.sourceX} ${attrs.sourceY} L${attrs.targetX} ${attrs.targetY}`" stroke-width="1" style="stroke: pink;"></path>
</template>

<script setup>
import { useAttrs } from 'vue';
const attrs = useAttrs();
</script>

节点

属性描述
id节点的唯一标识符
type节点类型,可以是默认类型,也可以是自定义类型
label节点标签
position节点的位置X、Y坐标
connectable禁用/启用连接节点
data传递到自定义组件的其他数据
deletable禁用/启用删除节点
dragHandle拖拽节点的句柄
draggable禁用/启用拖拽节点
expandParent扩展父区域以适合子节点
extent定义节点范围,即可以在其中移动节点的区域
focusable禁用/启用聚焦节点
height固定节点高度,作为样式应用 您可以传递一个将用于像素值的数字(高度:300 ->高度:300px)或传递一个带有单位的字符串(高度: 10rem ->高度:10rem
width固定节点宽度,作为样式应用 您可以传递一个将用于像素值的数字(宽度:300 ->宽度:300px)或传递一个带有单位的字符串(宽度: 10rem ->宽度:10rem
zIndex节点的z-index值
hidden禁用/启用隐藏节点
parentNode通过设置父节点 ID 将节点定义为子节点
selectable禁用/启用选择节点

添加节点

javascript
elementNodes.value.push({
    id: '2',
    label: 'Node 2',
    position: { x: 150, y: 50 },
})
javascript
import { VueFlow, useVueFlow } from '@vue-flow/core';
const { addNodes } = useVueFlow();
function generateRandomNode() {
    return {
        id: Math.random().toString(),
        position: { x: Math.random() * 500, y: Math.random() * 500 },
        label: 'Random Node',
    }
}
addNodes(generateRandomNode());

删除节点

javascript
elementNodes.value.pop();
javascript
import { VueFlow, useVueFlow } from '@vue-flow/core';

function onRemoveNode() {
    removeNodes('1')
}

function onRemoveNodes() {
    removeNodes(['1', '2'])
}

更新节点

javascript
function updateNodeExample(nodeId) {
    const node = elementNodes.value.find((node) => node.id === nodeId)
    node.label = 'Updated Node'
}
javascript
import  { useVueFlow } from '@vue-flow/core';

const instance = useVueFlow();
const node = instance.findNode(nodeId);

node.data = {
  ...node.data,
  hello: 'world',
}

节点事件

vue
<script setup>
import { ref } from 'vue'
import { VueFlow } from '@vue-flow/core'

const elements = ref([
    {
        id: '1',
        label: 'Node 1',
        position: { x: 50, y: 50 },
    },
])
</script>

<template>
    <!-- bind listeners to the event handlers -->
    <VueFlow
        v-model="elements"
        @node-drag-start="console.log('drag start', $event)"
        @node-drag="console.log('drag', $event)"
        @node-drag-stop="console.log('drag stop', $event)"
        @node-click="console.log('click', $event)"
        @node-double-click="console.log('dblclick', $event)"
        @node-contextmenu="console.log('contextmenu', $event)"
        @node-mouse-enter="console.log('mouseenter', $event)"
        @node-mouse-leave="console.log('mouseleave', $event)"
        @node-mouse-move="console.log('mousemove', $event)"
    />
</template>
vue
<script setup>
import { ref } from 'vue'  
import { VueFlow, useVueFlow } from '@vue-flow/core'

// useVueFlow provides access to the event handlers
const { 
    onNodeDragStart, 
    onNodeDrag,
    onNodeDragStop, 
    onNodeClick, 
    onNodeDoubleClick, 
    onNodeContextMenu, 
    onNodeMouseEnter, 
    onNodeMouseLeave, 
    onNodeMouseMove 
} = useVueFlow()
  
const elements = ref([
    {
        id: '1',
        label: 'Node 1',
        position: { x: 50, y: 50 },
    },
])
  
// bind listeners to the event handlers
onNodeDragStart((event) => {
    console.log('Node drag started', event)
})

onNodeDrag((event) => {
    console.log('Node dragged', event)
})

onNodeDragStop((event) => {
    console.log('Node drag stopped', event)
})
  
// ... and so on  
</script>

<template>
    <VueFlow v-model="elements" />
</template>

添加边

  • 可参考添加节点的示例
javascript
elementEdges.value.push({ id: 'e1-3', source: '1', target: '3' });

删除边

  • 可参考删除节点的示例
javascript
elementEdges.value.pop();

更新边

  • 可参考更新节点的示例
vue
const edge =elementEdges.value.find((edge) => edge.id === edgeId)
edge.source = '2'

边事件

vue
<script setup>
import { ref } from 'vue'
import { VueFlow } from '@vue-flow/core'

const elements = ref([
    {
        id: '1',
        label: 'Node 1',
        position: { x: 50, y: 50 },
    },
    {
        id: '2',
        label: 'Node 2',
        position: { x: 50, y: 250 },
    },
    {
        id: 'e1-2',
        source: '1',
        target: '2',
    },
])
</script>

<template>
    <!-- bind listeners to the event handlers -->
    <VueFlow
        v-model="elements"
        @edge-click="console.log('edge clicked', $event)"
        @edge-double-click="console.log('edge double clicked', $event)"
        @edge-context-menu="console.log('edge context menu', $event)"
        @edge-mouse-enter="console.log('edge mouse enter', $event)"
        @edge-mouse-leave="console.log('edge mouse leave', $event)"
        @edge-mouse-move="console.log('edge mouse move', $event)"
        @edge-update-start="console.log('edge update start', $event)"
        @edge-update="console.log('edge update', $event)"
        @edge-update-end="console.log('edge update end', $event)"
    />
</template>
vue
<script setup>
import { ref } from 'vue'  
import { VueFlow, useVueFlow } from '@vue-flow/core'

// useVueFlow provides access to the event handlers
const { 
    onEdgeClick,
    onEdgeDoubleClick,
    onEdgeContextMenu,
    onEdgeMouseEnter,
    onEdgeMouseLeave,
    onEdgeMouseMove,
    onEdgeUpdateStart,
    onEdgeUpdate,
    onEdgeUpdateEnd,
} = useVueFlow()
  
const elements = ref([
    {
        id: '1',
        label: 'Node 1',
        position: { x: 50, y: 50 },
    },
    {
        id: '2',
        label: 'Node 2',
        position: { x: 50, y: 250 },
    },
    {
        id: 'e1-2',
        source: '1',
        target: '2',
    },
])
  
// bind listeners to the event handlers
onEdgeClick((event, edge) => {
    console.log('edge clicked', edge)
})

onEdgeDoubleClick((event, edge) => {
    console.log('edge double clicked', edge)
})

onEdgeContextMenu((event, edge) => {
    console.log('edge context menu', edge)
})
  
// ... and so on  
</script>

<template>
    <VueFlow v-model="elements" />
</template>