节点简介
节点简介
节点是图形的底层组件。它们可以是您想要在图形中可视化的任何类型的数据,它们独立存在并通过边相互连接以创建数据图。
请记住,每个节点都是唯一的,因此需要一个唯一的 id和一个XY 位置。
有关节点可用选项的完整列表,请查看节点接口。
节点的增删改
向图中添加节点
通过将节点传递给Vue Flow 组件的nodes
prop(或已弃用的prop)来呈现节点。v-model
此方法_不会_产生任何变化。请参阅受控流部分以了解更多信息。
<script setup>
import { ref, onMounted } from 'vue'
import { VueFlow, Panel } from '@vue-flow/core'
const nodes = ref([
{
id: '1',
position: { x: 50, y: 50 },
data: { label: 'Node 1', },
}
]);
function addNode() {
const id = Date.now().toString()
nodes.value.push({
id,
position: { x: 150, y: 50 },
data: { label: `Node ${id}`, },
})
}
</script>
<template>
<VueFlow :nodes="nodes">
<Panel>
<button type="button" @click="addNode">Add a node</button>
</Panel>
</VueFlow>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import type { Node } from '@vue-flow/core'
import { VueFlow, Panel } from '@vue-flow/core'
const nodes = ref<Node[]>([
{
id: '1',
position: { x: 50, y: 50 },
data: { label: 'Node 1', },
}
]);
function addNode() {
const id = Date.now().toString()
nodes.value.push({
id,
position: { x: 150, y: 50 },
data: { label: `Node ${id}`, },
})
}
</script>
<template>
<VueFlow :nodes="nodes">
<Panel>
<button type="button" @click="addNode">Add a node</button>
</Panel>
</VueFlow>
</template>
如果您正在使用更复杂的图表或只是需要访问内部状态,则useVueFlow可组合项将会派上用场。
该addNodes
操作可通过useVueFlow获得,允许您直接将节点添加到状态。
而且,此操作不仅限于渲染图形的组件;它可以在其他地方使用,例如在侧边栏或工具栏中。
<script setup>
import { ref } from 'vue'
import { Panel, VueFlow, useVueFlow } from '@vue-flow/core'
const initialNodes = ref([
{
id: '1',
position: { x: 50, y: 50 },
data: { label: 'Node 1' },
}
])
const { addNodes } = useVueFlow()
function generateRandomNode() {
return {
id: Math.random().toString(),
position: { x: Math.random() * 500, y: Math.random() * 500 },
label: 'Random Node',
}
}
function onAddNode() {
// add a single node to the graph
addNodes(generateRandomNode())
}
function onAddNodes() {
// add multiple nodes to the graph
addNodes(Array.from({ length: 10 }, generateRandomNode))
}
</script>
<template>
<VueFlow :nodes="initialNodes">
<Panel>
<button type="button" @click="onAddNode">Add a node</button>
<button type="button" @click="onAddNodes">Add multiple nodes</button>
</Panel>
</VueFlow>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { Node } from '@vue-flow/core'
import { Panel, VueFlow, useVueFlow } from '@vue-flow/core'
const initialNodes = ref<Node[]>([
{
id: '1',
position: { x: 50, y: 50 },
data: { label: 'Node 1' },
}
])
const { addNodes } = useVueFlow()
function generateRandomNode() {
return {
id: Math.random().toString(),
position: { x: Math.random() * 500, y: Math.random() * 500 },
label: 'Random Node',
data: {
hello: 'world',
}
}
}
function onAddNode() {
// 向图中添加单个节点
addNodes(generateRandomNode())
}
function onAddNodes() {
// 向图中添加多个节点
addNodes(Array.from({ length: 10 }, generateRandomNode))
}
</script>
<template>
<VueFlow :nodes="initialNodes">
<Panel>
<button type="button" @click="onAddNode">Add a node</button>
<button type="button" @click="onAddNodes">Add multiple nodes</button>
</Panel>
</VueFlow>
</template>
如果要进行节点的双向绑定,请使用v-model:nodes="nodes"。这将允许您改变节点并将更改反映在图中。
从图中删除节点
mode-value
与添加节点类似,可以通过从(使用v-model
)或nodes
Vue Flow 组件的 prop中删除节点来从图中移除节点。
<script setup>
import { ref } from 'vue'
import { VueFlow, Panel } from '@vue-flow/core'
const nodes = ref([
{
id: '1',
position: { x: 50, y: 50 },
data: { label: 'Node 1' },
},
{
id: '2',
position: { x: 150, y: 50 },
data: { label: 'Node 2' },
}
])
function removeNode(id) {
nodes.value = nodes.value.filter((node) => node.id !== id)
}
</script>
<template>
<VueFlow :nodes="nodes">
<Panel>
<button type="button" @click="removeNode('1')">Remove Node 1</button>
<button type="button" @click="removeNode('2')">Remove Node 2</button>
</Panel>
</VueFlow>
</template>
该removeNodes
操作可通过useVueFlow获得,允许您直接从状态中删除节点。
您还可以在渲染图形的组件外部使用此操作,例如在侧边栏或工具栏中。
<script setup>
import { ref } from 'vue'
import { VueFlow, Panel, useVueFlow } from '@vue-flow/core'
const initialNodes = ref([
{
id: '1',
position: { x: 50, y: 50 },
data: { label: 'Node 1' },
},
{
id: '2',
position: { x: 150, y: 50 },
data: { label: 'Node 2' },
}
])
const { removeNodes } = useVueFlow()
function removeOneNode() {
removeNodes('1')
}
function removeMultipleNodes() {
removeNodes(['1', '2'])
}
</script>
<template>
<VueFlow :nodes="initialNodes">
<Panel>
<button type="button" @click="removeOneNode">Remove Node 1</button>
<button type="button" @click="removeMultipleNodes">Remove Node 1 and 2</button>
</Panel>
</VueFlow>
</template>
更新节点数据
由于节点是反应性对象,因此您可以随时通过简单地改变数据来更新其数据。这允许您随时禁用或启用句柄、更改标签,甚至向数据对象添加新属性。
有多种方法可以实现这一点,以下是一些示例:
import { useVueFlow } from '@vue-flow/core'
const instance = useVueFlow()
// use the `updateNodeData` method to update the data of an edge
instance.updateNodeData(edgeId, { hello: 'mona' })
// find the node in the state by its id
const node = instance.findNode(nodeId)
node.data = {
...node.data,
hello: 'world',
}
// you can also mutate properties like `selectable` or `draggable`
node.selectable = false
node.draggable = false
// or use `updateNode` to update the node directly
instance.updateNode(nodeId, { selectable: false, draggable: false })
<!-- CustomNode.vue -->
<script setup>
import { useNode } from '@vue-flow/core'
// `useNode` returns us the node object straight from the state
// since the node obj is reactive, we can mutate it to update our nodes' data
const { node } = useNode()
function onSomeEvent() {
node.data = {
...node.data,
hello: 'world',
}
// you can also mutate properties like `selectable` or `draggable`
node.selectable = false
node.draggable = false
}
</script>
<script setup>
import { ref } from 'vue'
const nodes = ref([
{
id: '1',
position: { x: 50, y: 50 },
data: {
label: 'Node 1',
hello: 'world',
}
},
])
function onSomeEvent(nodeId) {
const node = nodes.value.find((node) => node.id === nodeId)
node.data = {
...nodes.value[0].data,
hello: 'world',
}
// you can also mutate properties like `selectable` or `draggable`
node.selectable = false
node.draggable = false
}
</script>
<template>
<VueFlow :nodes="nodes">
<Panel>
<button type="button" @click="onSomeEvent('1')">Update Node 1</button>
</Panel>
</VueFlow>
</template>
预定义节点类型
Vue Flow 提供了几种可以立即使用的内置节点类型。 包括的节点类型有default
、input
和output
。
默认节点
默认节点包含两个句柄,作为地图中的分支连接点。
您可以自由地确定节点定义中句柄的位置。
import { ref } from 'vue'
import { Position } from '@vue-flow/core'
const nodes = ref([
{
id: '1',
type: 'default', // You can omit this as it's the fallback type
targetPosition: Position.Top, // or Bottom, Left, Right,
sourcePosition: Position.Bottom, // or Top, Left, Right,
data: { label: 'Default Node' },
}
])
(译者:这里有一个节点画布,但我这里显示不出来,请对照原文)
输入节点
输入节点具有单个手柄,默认情况下位于底部。它代表地图的起点。
import { ref } from 'vue'
import { Position } from '@vue-flow/core'
const nodes = ref([
{
id: '1',
type: 'input',
sourcePosition: Position.Bottom, // or Top, Left, Right,
data: { label: 'Input Node' },
}
])
(译者:这里有一个节点画布,但我这里显示不出来,请对照原文)
输出节点
输出节点也具有单个句柄,尽管它通常位于顶部。此节点代表地图的结束点。
import { ref } from 'vue'
import { Position } from '@vue-flow/core'
const nodes = ref([
{
id: '1',
type: 'output',
targetPosition: Position.Top, // or Bottom, Left, Right,
data: { label: 'Output Node' },
}
])
(译者:这里有一个节点画布,但我这里显示不出来,请对照原文)
用户定义节点
除了前面提到的默认节点类型之外,您还可以根据需要创建任意数量的自定义节点类型。节点类型由节点的定义决定。
(译者:懒了,不给代码了,请对照原文)
- App.vue
- CustomNode.vue
- App.vue
- CustomNode.vue
然后,Vue Flow 将尝试将此节点类型解析为组件。优先考虑状态的 nodeTypes 对象中的定义。接下来,它会尝试将该组件与全局注册的同名组件进行匹配。最后,它会搜索提供的模板槽(template slot)来填充节点类型。
如果没有方法在解析组件时产生结果,则使用默认节点类型作为后备。
模板槽(template-slots)
定义自定义节点的最简单方法之一是将它们作为模板插槽传递。针对用户定义的节点类型,动态解析插槽名称,这意味着具有类型的节点custom
预计会有一个名为的插槽#node-custom
。
<script setup>
import { VueFlow } from '@vue-flow/core'
import CustomNode from './CustomNode.vue'
const nodes = ref([
{
id: '1',
data: { label: 'Node 1' },
type: 'custom', // [!code]
position: { x: 50, y: 50 },
}
])
</script>
<template>
<VueFlow :nodes="nodes">
<!-- the expected slot name is `node-custom` -->
<template #node-custom="props"> // [!code]
<CustomNode v-bind="props" />
</template>
</VueFlow>
</template>