Skip to content

控制 Vue 流程

🌐 Taking Control of Vue Flow

WARNING

此 API 可能会在下一个主要版本中发生变化,届时将不再自动应用更改。

默认情况下,Vue Flow 会自动应用更改,所以你无需担心。

🌐 By default, Vue Flow will apply changes automatically, so you don't have to worry about it.

不过,在某些情况下,你需要控制变更,并在一些处理和验证之后手动应用它们。

🌐 Though, there are cases where you want to take control of changes and apply them manually after some processing and validations for example.

在本指南中,我们将学习如何控制更改并手动应用它们。

🌐 In this guide, we will learn how to take control of changes and apply them manually.

什么是Change

🌐 What is a Change?

“变化”是指任何由与流程的交互触发的操作,例如添加、更新(位置、选中状态)或删除节点或边,无论是通过拖拽、点击等方式,还是使用提供的 API。

🌐 A change is anything that is triggered by an interaction with the flow, like adding, updating (position, selected), or removing a node or an edge, either by dragging, clicking etc. or by using the provided API.

这些变化通过 onNodesChangeonEdgesChange 事件传达给用户空间。

🌐 These changes are communicated to the user-land through the onNodesChange and onEdgesChange events.

可能的更改包括:

🌐 Possible Changes include:

  • add:添加了一个节点或一条边。
  • remove:已删除一个节点或一条边。
  • select:已选择/取消选择一个节点或边。
  • position:节点位置已更新。
  • dimensions:节点的尺寸已更新。

WARNING

“更改”指任何流程上的变化,比如缩放或平移,或者只是更新节点的 data 对象。

为什么我更新节点时没有触发任何更改?

🌐 Why is no change emitted when I update a node?

Vue Flow 不会跟踪你的节点/边并尝试找出发生了什么变化,它只会在你与流程交互或使用 API 时触发更改。

🌐 Vue Flow will not track your nodes/edges and try to figure out what changed, it will only emit changes when you interact with the flow or use the API.

例如,这个 不会 触发更改:

🌐 For example this will not emit a change:

vue
<script setup>
import { ref } from 'vue'

const nodes = ref([
  {
    id: '1',
    position: { x: 0, y: 0 },
    data: { label: 'Node 1' },
  },
])

// this function *will not* emit a change
function removeNode() {
  nodes.value = nodes.value.filter((node) => node.id !== '1')
}
</script>

这是因为 Vue Flow 并不知道 id 为 1 的节点已被移除,它只知道用户或 API 触发的更改。

🌐 This is because Vue Flow does not know that the node with id 1 was removed, it only knows about changes that are triggered by the user or the API.

例如,这将触发一个变化:

🌐 This, for example, will emit a change:

vue
<script setup>
import { ref } from 'vue'
import { useVueFlow } from '@vue-flow/core'

const nodes = ref([
  {
    id: '1',
    position: { x: 0, y: 0 },
    data: { label: 'Node 1' },
  },
])

// this function *will* emit a change
const { removeNodes } = useVueFlow()

removeNodes('1')
</script>

applyDefault 选项

🌐 The applyDefault option

applyDefault 选项是一个可以传递给 <VueFlow> 组件的属性,用于启用或禁用自动变更处理。

🌐 The applyDefault option is a prop that can be passed to the <VueFlow> component to enable or disable automatic change handling.

通过将此选项设置为 false,我们告知 Vue Flow 不再自动应用更改,这样我们就可以控制更改并手动应用它们。

🌐 By setting this option to false, we tell Vue Flow to not apply changes automatically anymore, that way we can take control of changes and apply them manually.

vue
<template>
  <VueFlow :nodes="nodes" :edges="edges" :apply-default="false" />
</template>

onNodesChange / onEdgesChange 活动

🌐 onNodesChange / onEdgesChange events

Vue Flow 提供了两个事件,可以用于监听节点和边的变化。无论 applyDefault 选项如何,这些事件都会被触发,因此即使启用了自动变化,也可以使用它们来监听变化。

🌐 Vue Flow provides two events that can be used to listen to changes on nodes and edges. These events are emitted regardless of the applyDefault option, so you can use them to listen to changes even if you have automatic changes enabled.

vue
<script setup>
import { VueFlow, useVueFlow } from '@vue-flow/core'  

const { onNodesChange, onEdgesChange } = useVueFlow()

onNodesChange((changes) => {
  // changes are arrays of type `NodeChange`
  console.log(changes)
})

onEdgesChange((changes) => {
  // changes are arrays of type `EdgeChange`
  console.log(changes)
})
  
const onChange = (changes) => {
  // changes are arrays of type `NodeChange` or `EdgeChange`
  console.log(changes)
}
</script>

<template>
  <VueFlow :nodes="nodes" :edges="edges" @nodes-change="onChange" @edges-change="onChange" />
</template>

applyNodeChanges / applyEdgeChanges

Vue Flow 提供两个函数,可用于手动应用更改。

🌐 Vue Flow provides two functions that can be used to apply changes manually.

这些函数可以从 useVueFlow 可组合函数中使用。

🌐 These functions are available from the useVueFlow composable.

vue
<script setup>
import { useVueFlow } from '@vue-flow/core'

const { applyNodeChanges, applyEdgeChanges } = useVueFlow();

const onChange = (changes) => {
  // apply changes manually
  applyNodeChanges(changes)
}
</script>

验证更改

🌐 Validating Changes

利用我们刚刚学到的知识,我们现在可以控制更改并手动应用它们。

🌐 Using what we just learned, we can now take control of changes and apply them manually.

在此示例中,我们将首先使用 applyDefault 禁用自动更改处理程序,然后使用 onNodesChange 事件监听更改并验证删除更改,如果它们有效,则使用 applyNodeChanges 应用这些更改。

🌐 In this example, we will first disable automatic change handlers with applyDefault, then use the onNodesChange event to listen to changes and validate delete changes and, if they are valid, use applyNodeChanges to apply them.

INFO

查看确认删除示例

vue
<script setup>
import { ref } from 'vue'
import { useVueFlow, VueFlow } from '@vue-flow/core'

const { applyNodeChanges } = useVueFlow();

const { confirm } = useConfirm();

const nodes = ref([
  {
    id: '1',
    position: { x: 0, y: 0 },
    data: { label: 'Node 1' },
  },
  {
    id: '2',
    position: { x: 100, y: 100 },
    data: { label: 'Node 2' },
  },
])

const edges = ref([
  {
    id: 'e1->2',
    source: '1',
    target: '2',
  },
])

const onNodesChange = async (changes) => {
  const nextChanges = []

  for (const change of changes) {
    if (change.type === 'remove') {
      const isConfirmed = await confirm('Are you sure you want to delete this node?')

      if (isConfirmed) {
        nextChanges.push(change)
      }
    } else {
      nextChanges.push(change)
    }
  }

  applyNodeChanges(nextChanges)
}
</script>

<template>
  <VueFlow :nodes="nodes" :edges="edges" :apply-default="false" @nodes-change="onNodesChange" />
</template>

V-Model 节点和边

🌐 V-Model Nodes and Edges

在某些情况下,你可能希望将内部节点/边的状态与自己的状态同步,在这些情况下,你可以使用 v-model 指令将内部状态与自己的状态绑定。

🌐 In some cases you want to sync the state of internal nodes/edges with your own state, for those cases you can use the v-model directive to bind the internal state with your own state.

vue
<template>
  <VueFlow v-model:edges="edges" v-model:nodes="nodes" />
</template>

执行此操作会将内部状态与你自己的状态同步,这在你更新内部节点和边,但又希望这些更改反映在你自己的状态中的情况下非常有用。

🌐 Doing this will sync the internal state with your own state, which is useful for situations where you update internal nodes and edges but also want those changes to be reflected in your own state.

例如,如果你使用 updateNode 更新节点类型,并希望看到相同的更改反映在你自己的节点状态中,而不仅仅是在内部状态中。

🌐 For example, if you update the type of nodes using updateNode and want to see the same change reflected in your own nodes state and not just in the internal state.

vue
<script setup>
import { ref } from 'vue'
import { useVueFlow } from '@vue-flow/core'

const nodes = ref([
  {
    id: '1',
    position: { x: 0, y: 0 },
    data: { label: 'Node 1' },
  },
])

const { updateNode } = useVueFlow()

// using updateNode will only update the internal state, not the nodes state unless you use v-model
updateNode('1', { type: 'new-type' })
</script>

VueFlow 中文网 - 粤ICP备13048890号