运行示例窗口
示例窗口提示
- 红色按钮
恢复原始状态
- 黄色按钮
缩小/恢复
- 绿色按钮
开启画中画
- 可通过标题栏拖动窗口。
- 可拖动窗口右下角改变窗口大小。
开始
安装
bash
npm add @vue-flow/core
bash
pnpm add @vue-flow/core
bash
yarn add @vue-flow/core
示例
- 在 Vue Flow 中,应用程序结构由节点和边组成,所有这些都被归类为元素。
- 每个元素都需要一个唯一的 ID。
- 节点还需要一个 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>