Skip to content

Commit 4fe1a7b

Browse files
committed
refactor(core): add overloads to useVueFlow (#1481)
* refactor(core): add overloads to `useVueFlow` * chore(changeset): add * chore(core): cleanup
1 parent 9b4e3b2 commit 4fe1a7b

File tree

5 files changed

+37
-26
lines changed

5 files changed

+37
-26
lines changed

.changeset/red-avocados-know.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@vue-flow/core": minor
3+
---
4+
5+
Add overloads to `useVueFlow`. Allows calling `useVueFlow` with an `id` string only while emitting a deprecation warning for using the options obj.

packages/core/src/composables/useVueFlow.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { tryOnScopeDispose } from '@vueuse/core'
22
import type { EffectScope } from 'vue'
3-
import { effectScope, getCurrentScope, inject, provide, watch } from 'vue'
3+
import { effectScope, getCurrentInstance, getCurrentScope, inject, provide, watch } from 'vue'
44
import type { EdgeChange, FlowOptions, NodeChange, VueFlowStore } from '../types'
5-
import { warn } from '../utils'
5+
import { ErrorCode, VueFlowError, warn } from '../utils'
66
import { VueFlow } from '../context'
77
import { Storage } from '../utils/storage'
88

@@ -18,15 +18,21 @@ type Scope = (EffectScope & { vueFlowId: string }) | undefined
1818
* If no store instance is found in context, a new store instance is created and registered in storage
1919
*
2020
* @public
21-
* @param options - optional options to initialize the store instance
2221
* @returns a vue flow store instance
22+
* @param idOrOpts - id of the store instance or options to create a new store instance
2323
*/
24-
export function useVueFlow(options?: FlowOptions): VueFlowStore {
24+
export function useVueFlow(id?: string): VueFlowStore
25+
export function useVueFlow(options?: FlowOptions): VueFlowStore
26+
export function useVueFlow(idOrOpts?: any): VueFlowStore {
2527
const storage = Storage.getInstance()
2628

2729
const scope = getCurrentScope() as Scope
2830

29-
const id = options?.id
31+
const isOptsObj = typeof idOrOpts === 'object'
32+
33+
const options = isOptsObj ? idOrOpts : undefined
34+
35+
const id = options?.id ?? idOrOpts
3036
const vueFlowId = scope?.vueFlowId || id
3137

3238
let vueFlow: Injection
@@ -114,7 +120,7 @@ export function useVueFlow(options?: FlowOptions): VueFlowStore {
114120
})
115121
} else {
116122
// If options were passed, overwrite state with the options' values
117-
if (options) {
123+
if (isOptsObj) {
118124
vueFlow.setState(options)
119125
}
120126
}
@@ -126,8 +132,13 @@ export function useVueFlow(options?: FlowOptions): VueFlowStore {
126132
scope.vueFlowId = vueFlow.id
127133
}
128134

129-
if (options) {
130-
warn('options are deprecated and will be removed in the next major version. Use props on the `<VueFlow>` component instead.')
135+
if (isOptsObj) {
136+
const instance = getCurrentInstance()
137+
138+
// ignore the warning if we are in a VueFlow component
139+
if (instance?.type.name !== 'VueFlow') {
140+
vueFlow.emits.error(new VueFlowError(ErrorCode.USEVUEFLOW_OPTIONS))
141+
}
131142
}
132143

133144
return vueFlow

packages/core/src/composables/useWatchProps.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ export function useWatchProps(
309309
;(storeRef.value as any) = nextValue
310310
}
311311
},
312-
{ immediate: true, flush: 'pre' },
312+
{ immediate: true },
313313
)
314314
})
315315
}

packages/core/src/container/VueFlow/VueFlow.vue

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,12 @@ const modelValue = useVModel(props, 'modelValue', emit)
5656
const modelNodes = useVModel(props, 'nodes', emit)
5757
const modelEdges = useVModel(props, 'edges', emit)
5858
59-
const { vueFlowRef, hooks, getNodeTypes, getEdgeTypes, ...rest } = useVueFlow(props)
59+
const instance = useVueFlow(props)
6060
6161
// watch props and update store state
62-
const dispose = useWatchProps({ modelValue, nodes: modelNodes, edges: modelEdges }, props, {
63-
vueFlowRef,
64-
hooks,
65-
getNodeTypes,
66-
getEdgeTypes,
67-
...rest,
68-
})
62+
const dispose = useWatchProps({ modelValue, nodes: modelNodes, edges: modelEdges }, props, instance)
6963
70-
useHooks(emit, hooks)
64+
useHooks(emit, instance.hooks)
7165
7266
useOnInitHandler()
7367
@@ -83,13 +77,7 @@ onUnmounted(() => {
8377
dispose()
8478
})
8579
86-
defineExpose<VueFlowStore>({
87-
vueFlowRef,
88-
hooks,
89-
getNodeTypes,
90-
getEdgeTypes,
91-
...rest,
92-
})
80+
defineExpose<VueFlowStore>(instance)
9381
</script>
9482

9583
<script lang="ts">
@@ -100,7 +88,7 @@ export default {
10088
</script>
10189

10290
<template>
103-
<div ref="vueFlowRef" class="vue-flow">
91+
<div :ref="instance.vueFlowRef" class="vue-flow">
10492
<Viewport>
10593
<EdgeRenderer />
10694

packages/core/src/utils/errors.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export enum ErrorCode {
1414
EDGE_SOURCE_TARGET_SAME = 'EDGE_SOURCE_TARGET_SAME',
1515
EDGE_SOURCE_TARGET_MISSING = 'EDGE_SOURCE_TARGET_MISSING',
1616
EDGE_ORPHANED = 'EDGE_ORPHANED',
17+
18+
// deprecation errors
19+
USEVUEFLOW_OPTIONS = 'USEVUEFLOW_OPTIONS',
1720
}
1821

1922
const messages = {
@@ -36,6 +39,10 @@ const messages = {
3639
[ErrorCode.EDGE_ORPHANED]: (id: string) =>
3740
`Edge was orphaned (suddenly missing source or target) and has been removed\nEdge: ${id}`,
3841
[ErrorCode.EDGE_NOT_FOUND]: (id: string) => `Edge not found\nEdge: ${id}`,
42+
43+
// deprecation errors
44+
[ErrorCode.USEVUEFLOW_OPTIONS]: () =>
45+
`The options parameter is deprecated and will be removed in the next major version. Please use the id parameter instead`,
3946
} as const
4047

4148
type ErrorArgs<T extends ErrorCode> = (typeof messages)[T] extends (...args: any[]) => string

0 commit comments

Comments
 (0)