Appearance
状态
🌐 State
在底层,Vue Flow 使用 Provide/Inject 在组件之间传递其状态。你可以通过 useVueFlow 组合式函数访问内部状态。
🌐 Under the hood Vue Flow uses Provide/Inject to pass around it's state between components. You can access the internal state through the useVueFlow composable.
[useVueFlow](/guide/composables#usevueflow/) 可以用来创建一个新的状态实例并将其注入到当前组件树中,或者从当前上下文注入一个已存在的存储。内部状态可以被操作,例如通过向状态中添加新元素。该状态是响应式的,变化将会在图表上反映出来。
vue
<script setup>
import { useVueFlow } from '@vue-flow/core'
const { getNodes, onPaneReady } = useVueFlow()
// event handler
onPaneReady((i) => i.fitView())
// watch the stored nodes
watch(getNodes, (nodes) => console.log('nodes changed', nodes))
</script>访问内部状态
🌐 Accessing Internal State
使用组合式 API 还允许我们在当前组件上下文之外传递状态,因此在读取、写入和更新状态时,我们拥有更多的灵活性。
🌐 Using the composition API also allows us to pass the state around outside the current component context, thus we have a lot more flexibility when it comes to reading, writing and updating the state.
考虑以下示例,我们想要创建一个侧边栏,以便我们能够选择所有节点。
🌐 Consider this example, where we want to create a Sidebar that allows us to select all nodes.
vue
<!-- Container.vue -->
<template>
<div>
<Sidebar />
<div class="wrapper">
<VueFlow :nodes="nodes" :edges="edges" />
</div>
</div>
</template>我们可以将所有必要的信息作为 props 传递给 Sidebar,但这可能变得繁琐,或者导致 props 层层传递,而这是我们想要避免的。在这个例子中问题不大,但如果我们的目标组件在三层深的地方,就会很难跟踪信息的流向。
🌐 We could pass all necessary info as props to the Sidebar, which could become either tedious or result in prop drilling, which we want to avoid. In this example it wouldn't be a big issue but if our destination was 3 components deep, it would become hard to track the flow of information.
相反,我们可以在 Sidebar 初始化之前初始化一个 Vue Flow store 实例,这样该实例就可以作为组件树中的注入内容使用。
🌐 Instead, we can initialize a Vue Flow store instance before the Sidebar is initialized, thus the instance becomes available as an injection in the component tree.
vue
<script>
// Container.vue
import { useVueFlow } from '@vue-flow/core'
// initialize a store instance in this context, so it is available when calling inject(VueFlow)
useVueFlow()
</script>现在我们可以轻松地从侧边栏访问当前状态实例,而无需将它们作为属性传递。
🌐 Now we can easily access our current state instance from our Sidebar without passing them as props.
vue
<script setup>
import { useVueFlow } from '@vue-flow/core'
const { nodesSelectionActive, addSelectedNodes, getNodes } = useVueFlow()
const selectAll = () => {
addSelectedNodes(getNodes.value)
nodesSelectionActive.value = true
}
</script>
<template>
<aside>
<div class="description">
This is an example of how you can access the internal state outside of the Vue VueFlow component.
</div>
<div class="selectall">
<button @click="selectAll">select all nodes</button>
</div>
</aside>
</template>TIP
如果在同一上下文中有多个 store 实例,请确保给它们一个唯一的 ID,以确保访问到正确的实例。否则,useVueFlow 将尝试注入它在当前上下文中找到的第一个实例,这通常会是最后一个被注入的实例。
状态更新
🌐 State Updates
状态更新(如删除元素或更新位置)默认会自动应用。如果你想严格控制状态变化,可以通过将 applyDefault 选项/属性设置为 `false`` 来禁用此行为。
🌐 State updates like removing elements or updating positions are applied by default. If you want to strictly control state changes you can disable this behavior by setting the applyDefault option/prop to false.
vue
<template>
<VueFlow :nodes="nodes" :edges="edges" :apply-default="false" />
</template>onNodesChange 或 onEdgesChange 事件会触发状态变化,这些事件将提供一个已触发更改的数组。要控制状态变化,你可以实现自己的状态更新处理程序,或者使用库中提供的状态辅助函数来进行组合管理。
🌐 State changes are emitted by the onNodesChange or onEdgesChange events, which will provide an array of changes that have been triggered. To take control of state changes you can implement your own state update handlers or use the state helper functions that come with the library to mix it up.
INFO
在受控流程指南中了解更多信息。
在选项中访问状态 API
🌐 Access State in Options API
useVueFlow 是为组合式 API 设计的,但是 仍然可以在选项式 API 中使用它。虽然需要为你的 Vue Flow 状态实例传递一个唯一的 id,否则查找将会失败,并且 Vue Flow 在挂载时会创建一个新的状态实例。
vue
<script>
import { VueFlow, useVueFlow } from '@vue-flow/core'
const { addEdges, onConnect } = useVueFlow({ id: 'options-api' })
export default defineComponent({
components: { VueFlow },
data() {
return {
nodes: [
{
id: '1',
position: { x: 0, y: 0},
data: { label: 'Node 1' }
}
],
edges: [],
}
},
methods: {
// regular event handler
handleConnect: (params) => {
addEdges([params])
}
},
beforeMount() {
// Register your event handler, can technically be called in any lifecycle phase
// Skip this if you're using regular event handlers
onConnect((params) => addEdges([params]))
}
})
</script>
<template>
<VueFlow id="options-api" :nodes="nodes" :edges="edges" @connect="handleConnect" />
</template>