fix: Watcher not re-binding when initialized with empty arr
This commit is contained in:
@@ -28,11 +28,13 @@ const props = withDefaults(defineProps<FlowProps>(), {
|
|||||||
|
|
||||||
const emit = defineEmits([...Object.keys(createHooks()), 'update:modelValue', 'update:nodes', 'update:edges'])
|
const emit = defineEmits([...Object.keys(createHooks()), 'update:modelValue', 'update:nodes', 'update:edges'])
|
||||||
|
|
||||||
const modelProps = useVModels(props, emit)
|
const modelValue = useVModel(props, 'modelValue', emit)
|
||||||
|
const modelNodes = useVModel(props, 'nodes', emit)
|
||||||
|
const modelEdges = useVModel(props, 'edges', emit)
|
||||||
|
|
||||||
const { id, hooks, getNodeTypes, getEdgeTypes, ...rest } = useVueFlow()
|
const { id, hooks, getNodeTypes, getEdgeTypes, ...rest } = useVueFlow()
|
||||||
|
|
||||||
const dispose = useWatch(modelProps, { id, hooks, getNodeTypes, getEdgeTypes, ...rest })
|
const dispose = useWatch({ modelValue, nodes: modelNodes, edges: modelEdges }, props,{ id, hooks, getNodeTypes, getEdgeTypes, ...rest })
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
dispose()
|
dispose()
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Ref, ToRefs } from 'vue'
|
import { Ref, ToRefs } from 'vue'
|
||||||
import { WatchPausableReturn } from '@vueuse/core'
|
import { WatchPausableReturn } from '@vueuse/core'
|
||||||
import { FlowProps, VueFlowStore } from '~/types'
|
import { FlowProps, GraphEdge, GraphNode, VueFlowStore } from '~/types'
|
||||||
|
|
||||||
const isDef = <T>(val: T): val is NonNullable<T> => typeof val !== 'undefined'
|
const isDef = <T>(val: T): val is NonNullable<T> => typeof val !== 'undefined'
|
||||||
export default (models: ToRefs<FlowProps>, store: VueFlowStore) => {
|
export default (models: ToRefs<Pick<FlowProps, 'nodes' | 'edges' | 'modelValue'>>, props: FlowProps, store: VueFlowStore) => {
|
||||||
const scope = effectScope()
|
const scope = effectScope()
|
||||||
|
|
||||||
scope.run(() => {
|
scope.run(() => {
|
||||||
@@ -23,11 +23,12 @@ export default (models: ToRefs<FlowProps>, store: VueFlowStore) => {
|
|||||||
store.setElements(v)
|
store.setElements(v)
|
||||||
|
|
||||||
pauseStore = watchPausable(
|
pauseStore = watchPausable(
|
||||||
[() => store.edges.value.length, () => store.nodes.value.length],
|
[store.edges, store.nodes, () => store.edges.value.length, () => store.nodes.value.length],
|
||||||
() => {
|
([e, n]) => {
|
||||||
models.modelValue!.value = [...store.nodes.value, ...store.edges.value]
|
const val = [...(n as GraphNode[]), ...(e as GraphEdge[])]
|
||||||
|
if (val.length) models.modelValue!.value = val
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true, flush: 'post' },
|
||||||
)
|
)
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
@@ -58,7 +59,9 @@ export default (models: ToRefs<FlowProps>, store: VueFlowStore) => {
|
|||||||
|
|
||||||
pauseStore = watchPausable(
|
pauseStore = watchPausable(
|
||||||
() => store.nodes.value.length,
|
() => store.nodes.value.length,
|
||||||
() => (models.nodes!.value = [...store.nodes.value]),
|
() => {
|
||||||
|
if (store.nodes.value.length) models.nodes!.value = [...store.nodes.value]
|
||||||
|
},
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -90,7 +93,9 @@ export default (models: ToRefs<FlowProps>, store: VueFlowStore) => {
|
|||||||
|
|
||||||
pauseStore = watchPausable(
|
pauseStore = watchPausable(
|
||||||
() => store.edges.value.length,
|
() => store.edges.value.length,
|
||||||
() => (models.edges!.value = [...store.edges.value]),
|
() => {
|
||||||
|
if (store.edges.value.length) models.edges!.value = [...store.edges.value]
|
||||||
|
},
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -108,13 +113,13 @@ export default (models: ToRefs<FlowProps>, store: VueFlowStore) => {
|
|||||||
const watchMaxZoom = () => {
|
const watchMaxZoom = () => {
|
||||||
scope.run(() => {
|
scope.run(() => {
|
||||||
watch(
|
watch(
|
||||||
[() => models.maxZoom, models.maxZoom],
|
() => props.maxZoom,
|
||||||
() => {
|
() => {
|
||||||
if (models.maxZoom && isDef(models.maxZoom.value)) {
|
if (props.maxZoom && isDef(props.maxZoom)) {
|
||||||
store.setMaxZoom(models.maxZoom.value)
|
store.setMaxZoom(props.maxZoom)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: isDef(models.maxZoom?.value) },
|
{ immediate: isDef(props.maxZoom) },
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -122,13 +127,13 @@ export default (models: ToRefs<FlowProps>, store: VueFlowStore) => {
|
|||||||
const watchMinZoom = () => {
|
const watchMinZoom = () => {
|
||||||
scope.run(() => {
|
scope.run(() => {
|
||||||
watch(
|
watch(
|
||||||
[() => models.minZoom, models.minZoom],
|
() => props.minZoom,
|
||||||
() => {
|
() => {
|
||||||
if (models.minZoom && isDef(models.minZoom.value)) {
|
if (props.minZoom && isDef(props.minZoom)) {
|
||||||
store.setMinZoom(models.minZoom.value)
|
store.setMinZoom(props.minZoom)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: isDef(models.minZoom?.value) },
|
{ immediate: isDef(props.minZoom) },
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -136,13 +141,13 @@ export default (models: ToRefs<FlowProps>, store: VueFlowStore) => {
|
|||||||
const watchApplyDefault = () => {
|
const watchApplyDefault = () => {
|
||||||
scope.run(() => {
|
scope.run(() => {
|
||||||
watch(
|
watch(
|
||||||
[() => models.applyDefault, models.applyDefault],
|
() => props.applyDefault,
|
||||||
() => {
|
() => {
|
||||||
if (models.applyDefault && isDef(models.applyDefault.value)) {
|
if (props.applyDefault && isDef(props.applyDefault)) {
|
||||||
store.applyDefault.value = models.applyDefault.value
|
store.applyDefault.value = props.applyDefault
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: isDef(models.applyDefault?.value) },
|
{ immediate: isDef(props.applyDefault) },
|
||||||
)
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@@ -158,32 +163,31 @@ export default (models: ToRefs<FlowProps>, store: VueFlowStore) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
watchModelValue()
|
const watchRest = () => {
|
||||||
watchNodesValue()
|
const skip = ['id', 'modelValue', 'edges', 'nodes', 'maxZoom', 'minZoom', 'applyDefault']
|
||||||
watchEdgesValue()
|
Object.keys(props).forEach((prop) => {
|
||||||
watchMaxZoom()
|
if (!skip.includes(prop)) {
|
||||||
watchMinZoom()
|
const model = props[prop as keyof typeof props]
|
||||||
watchApplyDefault()
|
const storedValue = (<any>store)[prop] as Ref
|
||||||
|
|
||||||
const skip = ['id', 'modelValue', 'edges', 'nodes', 'maxZoom', 'minZoom', 'applyDefault']
|
scope.run(() => {
|
||||||
Object.keys(models).forEach((m) => {
|
watch(
|
||||||
if (!skip.includes(m)) {
|
() => model,
|
||||||
const model = models[m as keyof typeof models]
|
() => {
|
||||||
const storedValue = (<any>store)[m] as Ref
|
if (model && isDef(model)) {
|
||||||
|
storedValue.value = model
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: isDef(model) },
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
scope.run(() => {
|
;[watchModelValue, watchNodesValue, watchEdgesValue, watchMinZoom, watchMaxZoom, watchApplyDefault, watchRest].forEach(
|
||||||
watch(
|
(watch) => watch(),
|
||||||
[() => model, model],
|
)
|
||||||
() => {
|
|
||||||
if (model && isDef(model.value)) {
|
|
||||||
storedValue.value = model.value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ immediate: isDef(model?.value) },
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return () => scope.stop()
|
return () => scope.stop()
|
||||||
|
|||||||
Reference in New Issue
Block a user