docs(guide): update edge page
This commit is contained in:
+387
-178
@@ -1,5 +1,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { VueFlow } from '@vue-flow/core';
|
import LogosJavascript from '~icons/logos/javascript';
|
||||||
|
import LogosTypescript from '~icons/logos/typescript-icon';
|
||||||
|
import { VueFlow, Panel } from '@vue-flow/core';
|
||||||
import { Background } from '@vue-flow/background';
|
import { Background } from '@vue-flow/background';
|
||||||
import Check from '~icons/mdi/check';
|
import Check from '~icons/mdi/check';
|
||||||
import Close from '~icons/mdi/close';
|
import Close from '~icons/mdi/close';
|
||||||
@@ -69,66 +71,102 @@ const straightEdge = ref([
|
|||||||
]);
|
]);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
# Edges
|
# Introduction to Edges
|
||||||
|
|
||||||
Edges are what connects your nodes into a map.
|
Edges are the links connecting your nodes, forming a map.
|
||||||
|
Each edge runs from one handle to another, and can be customized to your liking.
|
||||||
|
|
||||||
They cannot exist on their own and need nodes to which they are connected.
|
Remember, every edge is unique and thus **requires a unique id**, a source and target node id.
|
||||||
|
|
||||||
Each edge <span class="font-bold text-blue-500">requires a unique id, a source node and a target node id.</span>
|
For the full list of options available for an edge, check out the [Edge Type](/typedocs/types/Edge).
|
||||||
|
|
||||||
You can view the full options-list for an edge [here](/typedocs/types/Edge).
|
## Adding Edges to the Graph
|
||||||
|
|
||||||
## Usage
|
Edges are generally created by adding them to the `mode-value` (using `v-model`) or to the `edges` prop of the Vue Flow component.
|
||||||
|
This can be done dynamically at any point in your component's lifecycle.
|
||||||
|
|
||||||
Generally you create edges by adding them to the model-value or the edges prop of the Vue Flow component.
|
:::code-group
|
||||||
|
|
||||||
```vue
|
```vue [<LogosJavascript />]
|
||||||
<script>
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
import { VueFlow } from '@vue-flow/core'
|
import { VueFlow } from '@vue-flow/core'
|
||||||
|
|
||||||
export default defineComponent({
|
const elements = ref([
|
||||||
components: { VueFlow },
|
{
|
||||||
data() {
|
id: '1',
|
||||||
return {
|
position: { x: 50, y: 50 },
|
||||||
elements: [
|
label: 'Node 1',
|
||||||
{
|
|
||||||
id: '1',
|
|
||||||
position: { x: 50, y: 50 },
|
|
||||||
label: 'Node 1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2',
|
|
||||||
position: { x: 50, y: 250 },
|
|
||||||
label: 'Node 2',
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
mounted() {
|
{
|
||||||
// Add an edge after mount
|
id: '2',
|
||||||
this.elements.push(
|
position: { x: 50, y: 250 },
|
||||||
{
|
label: 'Node 2',
|
||||||
id: 'e1-2',
|
|
||||||
source: '1',
|
|
||||||
target: '2',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
elements.value.push({
|
||||||
|
id: 'e1-2',
|
||||||
|
source: '1',
|
||||||
|
target: '2',
|
||||||
|
})
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div style="height: 300px">
|
<VueFlow v-model="elements"/>
|
||||||
<VueFlow v-model="elements" />
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
For more advanced graphs that require more state access you will want to use the useVueFlow composable.
|
```vue [<LogosTypescript />]
|
||||||
[useVueFlow](/typedocs/functions/useVueFlow) will provide the [`addEdges`](/typedocs/interfaces/Actions#addedges/) action,
|
|
||||||
which you can use to add edges directly to the state.
|
|
||||||
|
|
||||||
```vue
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import type { Elements } from '@vue-flow/core'
|
||||||
|
import { VueFlow } from '@vue-flow/core'
|
||||||
|
|
||||||
|
const elements = ref<Elements>([
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
position: { x: 50, y: 50 },
|
||||||
|
label: 'Node 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
position: { x: 50, y: 250 },
|
||||||
|
label: 'Node 2',
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
elements.value.push({
|
||||||
|
id: 'e1-2',
|
||||||
|
source: '1',
|
||||||
|
target: '2',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<VueFlow v-model="elements"/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
If you are working with more complex graphs that necessitate extensive state access, the `useVueFlow` composable should
|
||||||
|
be employed.
|
||||||
|
The [`addEdges`](/typedocs/interfaces/Actions#addEdges) action is available
|
||||||
|
through [useVueFlow](/typedocs/functions/useVueFlow), allowing you to add edges straight to the state.
|
||||||
|
|
||||||
|
What's more, this action isn't limited to the component rendering the graph; it can be utilized elsewhere, like in a
|
||||||
|
Sidebar or Toolbar.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
|
||||||
|
```vue [<LogosJavascript />]
|
||||||
<script setup>
|
<script setup>
|
||||||
import { VueFlow, useVueFlow } from '@vue-flow/core'
|
import { VueFlow, useVueFlow } from '@vue-flow/core'
|
||||||
|
|
||||||
@@ -144,41 +182,85 @@ const initialNodes = ref([
|
|||||||
label: 'Node 2',
|
label: 'Node 2',
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
const { addEdges } = useVueFlow({
|
|
||||||
nodes: initialNodes,
|
const { addEdges } = useVueFlow()
|
||||||
})
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// Add an edge after mount
|
// add an edge after mount
|
||||||
addEdges([
|
addEdges([
|
||||||
{
|
{
|
||||||
source: '1',
|
source: '1',
|
||||||
target: '2',
|
target: '2',
|
||||||
|
|
||||||
|
// if a node has multiple handles of the same type,
|
||||||
|
// you should specify which handle to use by id
|
||||||
sourceHandle: null,
|
sourceHandle: null,
|
||||||
targetHandle: null,
|
targetHandle: null,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div style="height: 300px">
|
<VueFlow :nodes="initialNodes" />
|
||||||
<VueFlow />
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
## [Default Edge-Types](/typedocs/interfaces/DefaultEdgeTypes)
|
```vue [<LogosTypescript />]
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { Node } from '@vue-flow/core'
|
||||||
|
import { VueFlow, useVueFlow } from '@vue-flow/core'
|
||||||
|
|
||||||
Vue Flow comes with built-in edges that you can use right out of the box.
|
const initialNodes = ref<Node[]>([
|
||||||
These edge types include `default` (bezier), `step`, `smoothstep` and `straight`.
|
{
|
||||||
|
id: '1',
|
||||||
|
position: { x: 50, y: 50 },
|
||||||
|
label: 'Node 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
position: { x: 50, y: 250 },
|
||||||
|
label: 'Node 2',
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const { addEdges } = useVueFlow()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// add an edge after mount
|
||||||
|
addEdges([
|
||||||
|
{
|
||||||
|
source: '1',
|
||||||
|
target: '2',
|
||||||
|
|
||||||
|
// if a node has multiple handles of the same type,
|
||||||
|
// you should specify which handle to use by id
|
||||||
|
sourceHandle: null,
|
||||||
|
targetHandle: null,
|
||||||
|
}
|
||||||
|
])
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<VueFlow :nodes="initialNodes" />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
## [Predefined Edge-Types](/typedocs/interfaces/DefaultEdgeTypes)
|
||||||
|
|
||||||
|
Vue Flow provides several built-in edge types that you can leverage immediately.
|
||||||
|
The included node types are `default` (bezier), `step`, `smoothstep` and `straight`.
|
||||||
|
|
||||||
### Default Edge (Bezier)
|
### Default Edge (Bezier)
|
||||||
|
|
||||||
The default edge is a bezier curve that connects two nodes.
|
The default edge is a bezier curve that connects two nodes.
|
||||||
|
|
||||||
<div class="mt-4 bg-[var(--vp-code-block-bg)] rounded h-50">
|
<div class="mt-4 bg-[var(--vp-code-block-bg)] rounded-lg h-50">
|
||||||
<VueFlow v-model="bezierEdge">
|
<VueFlow v-model="bezierEdge">
|
||||||
<Background />
|
<Background class="rounded-lg" />
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -186,9 +268,9 @@ The default edge is a bezier curve that connects two nodes.
|
|||||||
|
|
||||||
A step edge has a straight path with a step towards the target.
|
A step edge has a straight path with a step towards the target.
|
||||||
|
|
||||||
<div class="mt-4 bg-[var(--vp-code-block-bg)] rounded h-50">
|
<div class="mt-4 bg-[var(--vp-code-block-bg)] rounded-lg h-50">
|
||||||
<VueFlow v-model="stepEdge">
|
<VueFlow v-model="stepEdge">
|
||||||
<Background />
|
<Background class="rounded-lg" />
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -196,9 +278,9 @@ A step edge has a straight path with a step towards the target.
|
|||||||
|
|
||||||
The same as the step edge though with a border radius on the step (rounded step).
|
The same as the step edge though with a border radius on the step (rounded step).
|
||||||
|
|
||||||
<div class="mt-4 bg-[var(--vp-code-block-bg)] rounded h-50">
|
<div class="mt-4 bg-[var(--vp-code-block-bg)] rounded-lg h-50">
|
||||||
<VueFlow v-model="smoothStepEdge">
|
<VueFlow v-model="smoothStepEdge">
|
||||||
<Background />
|
<Background class="rounded-lg" />
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -206,42 +288,155 @@ The same as the step edge though with a border radius on the step (rounded step)
|
|||||||
|
|
||||||
A simple straight path.
|
A simple straight path.
|
||||||
|
|
||||||
<div class="mt-4 bg-[var(--vp-code-block-bg)] rounded h-50">
|
<div class="mt-4 bg-[var(--vp-code-block-bg)] rounded-lg h-50">
|
||||||
<VueFlow v-model="straightEdge">
|
<VueFlow v-model="straightEdge">
|
||||||
<Background />
|
<Background class="rounded-lg" />
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Custom Edges
|
## User-Defined Edges
|
||||||
|
|
||||||
In addition to the default edge types from the previous chapter, you can define any amount of custom edge-types.
|
On top of the default edge types mentioned earlier, you can create as many custom edge-types as you need.
|
||||||
Edge-types are inferred from your edge's definition.
|
Edge-types are determined from your edges' definitions.
|
||||||
|
|
||||||
```js{4}
|
::: code-group
|
||||||
const edges = [
|
|
||||||
|
```js [edges <LogosJavascript />]
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export const edges = ref([
|
||||||
{
|
{
|
||||||
id: 'e1-2',
|
id: 'e1-2',
|
||||||
type: 'custom',
|
|
||||||
source: '1',
|
source: '1',
|
||||||
target: '2',
|
target: '2',
|
||||||
|
// this will create the edge-type `custom`
|
||||||
|
type: 'custom',
|
||||||
},
|
},
|
||||||
]
|
{
|
||||||
|
id: 'e1-2',
|
||||||
|
source: '1',
|
||||||
|
target: '2',
|
||||||
|
// this will create the edge-type `special`
|
||||||
|
type: 'special',
|
||||||
|
}
|
||||||
|
])
|
||||||
```
|
```
|
||||||
|
|
||||||
Vue Flow will now try to resolve this edge-type to a component.
|
```vue [CustomEdge.vue <LogosJavascript />]
|
||||||
First and foremost we will look for a definition in the `edgeTypes` object of the state.
|
<script setup>
|
||||||
After that we will try to resolve the component to a globally registered one that matches the exact name.
|
import { BezierEdge } from '@vue-flow/core';
|
||||||
Finally, we will check if a template slot has been provided to fill the edge-type.
|
|
||||||
|
|
||||||
If none of these methods succeed in resolving the component the default (bezier) edge-type will be used as a fallback.
|
const props = defineProps(['sourceX', 'sourceY', 'targetX', 'targetY', 'sourcePosition', 'targetPosition']);
|
||||||
|
|
||||||
|
console.log(props.data.hello) // 'world'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'CustomEdge',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<BezierEdge
|
||||||
|
:source-x="sourceX"
|
||||||
|
:source-y="sourceY"
|
||||||
|
:target-x="targetX"
|
||||||
|
:target-y="targetY"
|
||||||
|
:source-position="sourcePosition"
|
||||||
|
:target-position="targetPosition"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
```ts [edges <LogosTypescript />]
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import type { Edge } from '@vue-flow/core'
|
||||||
|
|
||||||
|
// You can pass 3 optional generic arguments to the Edge type, allowing you to define:
|
||||||
|
// 1. The data object type
|
||||||
|
// 2. The events object type
|
||||||
|
// 3. The possible edge types
|
||||||
|
|
||||||
|
interface CustomData {
|
||||||
|
hello: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CustomEdgeTypes = 'custom' | 'special'
|
||||||
|
|
||||||
|
type CustomEdge = Edge<CustomEdgeData, any, CustomEdgeTypes>
|
||||||
|
|
||||||
|
export const edges = ref<CustomEdge[]>([
|
||||||
|
{
|
||||||
|
id: 'e1-2',
|
||||||
|
source: '1',
|
||||||
|
target: '2',
|
||||||
|
// this will create the edge-type `custom`
|
||||||
|
type: 'custom',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'e1-2',
|
||||||
|
source: '1',
|
||||||
|
target: '2',
|
||||||
|
// this will create the edge-type `special`
|
||||||
|
type: 'special',
|
||||||
|
},
|
||||||
|
|
||||||
|
// this will throw a type error, as the type is not defined in the CustomEdgeTypes
|
||||||
|
// regardless it would be rendered as a default edge type
|
||||||
|
{
|
||||||
|
id: 'e1-2',
|
||||||
|
source: '1',
|
||||||
|
target: '2',
|
||||||
|
type: 'not-defined',
|
||||||
|
}
|
||||||
|
])
|
||||||
|
```
|
||||||
|
|
||||||
|
```vue [CustomEdge.vue <LogosTypescript />]
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { EdgeProps } from '@vue-flow/core';
|
||||||
|
import { BezierEdge } from '@vue-flow/core';
|
||||||
|
|
||||||
|
import { CustomData } from './edges'
|
||||||
|
|
||||||
|
const props = defineProps<EdgeProps<CustomData>>();
|
||||||
|
|
||||||
|
console.log(props.data.hello) // 'world'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'CustomEdge',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<BezierEdge
|
||||||
|
:source-x="sourceX"
|
||||||
|
:source-y="sourceY"
|
||||||
|
:target-x="targetX"
|
||||||
|
:target-y="targetY"
|
||||||
|
:source-position="sourcePosition"
|
||||||
|
:target-position="targetPosition"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
Vue Flow will then attempt to resolve this edge-type to a component.
|
||||||
|
Priority is given to a definition in the edgeTypes object of the state.
|
||||||
|
Next, it tries to match the component to a globally registered one with the same name.
|
||||||
|
Finally, it searches for a provided template slot to fill in the edge-type.
|
||||||
|
|
||||||
|
If no methods produce a result in resolving the component, the default edge-type is used as a fallback.
|
||||||
|
|
||||||
### Template slots
|
### Template slots
|
||||||
|
|
||||||
The easiest way to define custom edges is, by passing them as template slots.
|
One of the easiest ways to define custom edges is, by passing them as template slots.
|
||||||
Your custom edge-types are dynamically resolved to slot-names, meaning an edge with the type `custom`
|
Dynamic resolution to slot-names is done for your user-defined edge-types,
|
||||||
will expect a slot to have the name `edge-custom`.
|
meaning a edge with the type `custom` is expected to have a slot named `#edge-custom`.
|
||||||
|
|
||||||
You can choose any name you want for your edge-type, and it will be resolved to the corresponding slot (i.e. `my-edge-type` -> `#edge-my-edge-type`)
|
|
||||||
|
|
||||||
```vue{18,26}
|
```vue{18,26}
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -278,13 +473,10 @@ const elements = ref([
|
|||||||
|
|
||||||
### Edge-types object
|
### Edge-types object
|
||||||
|
|
||||||
You can also define edge-types by passing an object as a prop to the VueFlow component (or as an option to the
|
Alternatively, edge-types can also be defined by passing an object as a prop to the VueFlow component (or as an option to the composable).
|
||||||
composable).
|
|
||||||
|
|
||||||
::: warning
|
::: warning
|
||||||
When doing this, mark your components as raw (using the designated function from the vue library) to avoid them being
|
Take precaution to mark your components as raw (utilizing the marked function from the Vue library) to prevent their conversion into reactive objects. Otherwise, Vue will display a warning on the console.
|
||||||
turned into reactive objects.
|
|
||||||
Otherwise, vue will throw a warning in the console.
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
```vue{5-7,28}
|
```vue{5-7,28}
|
||||||
@@ -320,57 +512,10 @@ const elements = ref([
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Edge Template
|
## [Edge Props](/typedocs/interfaces/EdgeProps)
|
||||||
|
|
||||||
You can also set a template per edge, which will overwrite the edge-type component but will retain
|
Your custom edges are enclosed so that fundamental functions like selecting operate.
|
||||||
the type otherwise.
|
But you may wish to expand on these features or implement your business logic inside edges, thus your edges receive the following properties:
|
||||||
|
|
||||||
```vue{30}
|
|
||||||
<script setup>
|
|
||||||
import { markRaw } from 'vue'
|
|
||||||
import CustomEdge from './CustomEdge.vue'
|
|
||||||
|
|
||||||
const elements = ref([
|
|
||||||
{
|
|
||||||
id: '1',
|
|
||||||
label: 'Node 1',
|
|
||||||
position: { x: 0, y: 0 },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2',
|
|
||||||
label: 'Node 2',
|
|
||||||
position: { x: 0, y: 150 },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3',
|
|
||||||
label: 'Node 3',
|
|
||||||
position: { x: 0, y: 300 },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'e1-2',
|
|
||||||
source: '1',
|
|
||||||
target: '2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'e1-3',
|
|
||||||
source: '1',
|
|
||||||
target: '2',
|
|
||||||
template: markRaw(CustomEdge),
|
|
||||||
},
|
|
||||||
])
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<div style="height: 300px">
|
|
||||||
<VueFlow v-model="elements" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
### [Custom Edge Props](/typedocs/interfaces/EdgeProps)
|
|
||||||
|
|
||||||
Your custom edges are wrapped so that the basic functions like selecting work.
|
|
||||||
But you might want to extend on that functionality or implement your own business logic inside of edges, therefore
|
|
||||||
your edges receive the following props:
|
|
||||||
|
|
||||||
| Name | Definition | Type | Optional |
|
| Name | Definition | Type | Optional |
|
||||||
|---------------------|-------------------------------|------------------------------------------------|--------------------------------------------|
|
|---------------------|-------------------------------|------------------------------------------------|--------------------------------------------|
|
||||||
@@ -400,14 +545,74 @@ your edges receive the following props:
|
|||||||
| markerStart | Edge marker id | string | <Check class="text-[var(--vp-c-brand)]" /> |
|
| markerStart | Edge marker id | string | <Check class="text-[var(--vp-c-brand)]" /> |
|
||||||
| curvature | Edge path curvature | number | <Check class="text-[var(--vp-c-brand)]" /> |
|
| curvature | Edge path curvature | number | <Check class="text-[var(--vp-c-brand)]" /> |
|
||||||
|
|
||||||
### (Custom) Edge Events
|
## Edge Events
|
||||||
|
|
||||||
In addition to the event handlers that you can access through [`useVueFlow`](/guide/composables#useVueFlow/) or the Vue Flow component,
|
Vue Flow provides two main ways of listening to edge events,
|
||||||
you can also pass in event handlers in your initial edge definition, or you can access the edge events through the `events` prop passed
|
either by using `useVueFlow` to bind listeners to the event handlers
|
||||||
to your edge components.
|
or by using binding listeners to the `<VueFlow>` component.
|
||||||
|
|
||||||
```vue{19-26}
|
::: code-group
|
||||||
|
|
||||||
|
```vue [useVueFlow]
|
||||||
<script setup>
|
<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>
|
||||||
|
```
|
||||||
|
|
||||||
|
```vue [component]
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
import { VueFlow } from '@vue-flow/core'
|
import { VueFlow } from '@vue-flow/core'
|
||||||
|
|
||||||
const elements = ref([
|
const elements = ref([
|
||||||
@@ -419,53 +624,57 @@ const elements = ref([
|
|||||||
{
|
{
|
||||||
id: '2',
|
id: '2',
|
||||||
label: 'Node 2',
|
label: 'Node 2',
|
||||||
position: { x: 50, y: 150 },
|
position: { x: 50, y: 250 },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'edge1-2',
|
id: 'e1-2',
|
||||||
source: '1',
|
source: '1',
|
||||||
target: '2',
|
target: '2',
|
||||||
events: {
|
},
|
||||||
click: () => {
|
|
||||||
console.log('Edge clicked')
|
|
||||||
},
|
|
||||||
change: () => {
|
|
||||||
console.log('Something changed')
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
])
|
])
|
||||||
</script>
|
</script>
|
||||||
```
|
|
||||||
|
|
||||||
As you can see above, you can also pass in custom event handlers. These will not be called by Vue Flow but can be used
|
|
||||||
to forward callback functions to your custom components.
|
|
||||||
The `click` handler is part of the [`EdgeEventsHandler`](/typedocs/types/EdgeEventsHandler) type, meaning it will be
|
|
||||||
triggered when the edge is clicked.
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { EdgeProps, EdgeEventsOn } from '@vue-flow/core'
|
|
||||||
|
|
||||||
// define your events
|
|
||||||
interface CustomEdgeEvents {
|
|
||||||
click: EdgeEventsOn['click']
|
|
||||||
customEvent: (input: string) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CustomEdgeProps extends EdgeProps<any, CustomEdgeEvents> {
|
|
||||||
id: string
|
|
||||||
events: CustomEdgeEvents
|
|
||||||
}
|
|
||||||
|
|
||||||
props.events.click(() => {
|
|
||||||
console.log(`Edge ${props.id} clicked`)
|
|
||||||
})
|
|
||||||
|
|
||||||
// custom events are just functions, they are not hooks which you can listen to like `click`
|
|
||||||
props.events.customEvent('custom event triggered')
|
|
||||||
</script>
|
|
||||||
<template>
|
<template>
|
||||||
<!-- Omitted for simplicty -->
|
<!-- 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>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
<div class="mt-4 bg-[var(--vp-code-block-bg)] rounded-lg h-50">
|
||||||
|
<VueFlow
|
||||||
|
v-model="bezierEdge"
|
||||||
|
@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)"
|
||||||
|
>
|
||||||
|
<Panel position="top-center">
|
||||||
|
<p class="text-sm">Interact to see events in browser console</p>
|
||||||
|
</Panel>
|
||||||
|
<Background class="rounded-lg" />
|
||||||
|
</VueFlow>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## Customizing Appearance
|
||||||
|
|
||||||
|
::: tip
|
||||||
|
To override the styles of the default theme, visit the [Theming section](/guide/theming).
|
||||||
|
:::
|
||||||
|
|||||||
Reference in New Issue
Block a user