Appearance
节点简介
¥Introduction to Nodes
节点是图表的底层组件。它们可以是你想要在图表中可视化的任何类型的数据,它们独立存在,并通过边相互连接以创建数据图。
¥Nodes are the underlying components of your graph. They can be any kind of data you want to visualize in your graph, existing independently and being interconnected through edges to create a data map.
请记住,每个节点都是唯一的,因此需要一个唯一的 ID 和一个 XY 位置。
¥Remember, every node is unique and thus requires a unique id and an XY-position.
有关节点可用选项的完整列表,请查看 节点接口。
¥For the full list of options available for a node, check out the Node Interface.
向图中添加节点
¥Adding Nodes to the Graph
节点通过将节点传递给 Vue Flow 组件的 nodes
属性(或已弃用的 v-model
属性)来渲染。
¥Nodes are rendered by passing them to the nodes
prop (or the deprecated v-model
prop) of the Vue Flow component.
警告
此方法不会创建更改。查看 受控流程 部分了解更多信息。
¥This method will not create a change. Check out the Controlled Flow section for more information.
vue
<script setup>
import { ref, onMounted } from 'vue'
import { VueFlow, Panel } from '@vue-flow/core'
const nodes = ref([
{
id: '1',
position: { x: 50, y: 50 },
data: { label: 'Node 1', },
}
]);
function addNode() {
const id = Date.now().toString()
nodes.value.push({
id,
position: { x: 150, y: 50 },
data: { label: `Node ${id}`, },
})
}
</script>
<template>
<VueFlow :nodes="nodes">
<Panel>
<button type="button" @click="addNode">Add a node</button>
</Panel>
</VueFlow>
</template>
vue
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import type { Node } from '@vue-flow/core'
import { VueFlow, Panel } from '@vue-flow/core'
const nodes = ref<Node[]>([
{
id: '1',
position: { x: 50, y: 50 },
data: { label: 'Node 1', },
}
]);
function addNode() {
const id = Date.now().toString()
nodes.value.push({
id,
position: { x: 150, y: 50 },
data: { label: `Node ${id}`, },
})
}
</script>
<template>
<VueFlow :nodes="nodes">
<Panel>
<button type="button" @click="addNode">Add a node</button>
</Panel>
</VueFlow>
</template>
如果你正在处理更复杂的图表,或者只是需要访问内部状态,useVueFlow 可组合项将会派上用场。
¥If you are working with more complex graphs or simply require access to the internal state, the useVueFlow composable will come in handy.
addNodes
操作可通过 useVueFlow 获得,允许你直接向状态添加节点。
¥The addNodes
action is available through useVueFlow, allowing you to add nodes 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.
vue
<script setup>
import { ref } from 'vue'
import { Panel, VueFlow, useVueFlow } from '@vue-flow/core'
const initialNodes = ref([
{
id: '1',
position: { x: 50, y: 50 },
data: { label: 'Node 1' },
}
])
const { addNodes } = useVueFlow()
function generateRandomNode() {
return {
id: Math.random().toString(),
position: { x: Math.random() * 500, y: Math.random() * 500 },
label: 'Random Node',
}
}
function onAddNode() {
// add a single node to the graph
addNodes(generateRandomNode())
}
function onAddNodes() {
// add multiple nodes to the graph
addNodes(Array.from({ length: 10 }, generateRandomNode))
}
</script>
<template>
<VueFlow :nodes="initialNodes">
<Panel>
<button type="button" @click="onAddNode">Add a node</button>
<button type="button" @click="onAddNodes">Add multiple nodes</button>
</Panel>
</VueFlow>
</template>
vue
<script setup lang="ts">
import { ref } from 'vue'
import type { Node } from '@vue-flow/core'
import { Panel, VueFlow, useVueFlow } from '@vue-flow/core'
const initialNodes = ref<Node[]>([
{
id: '1',
position: { x: 50, y: 50 },
data: { label: 'Node 1' },
}
])
const { addNodes } = useVueFlow()
function generateRandomNode() {
return {
id: Math.random().toString(),
position: { x: Math.random() * 500, y: Math.random() * 500 },
label: 'Random Node',
data: {
hello: 'world',
}
}
}
function onAddNode() {
// add a single node to the graph
addNodes(generateRandomNode())
}
function onAddNodes() {
// add multiple nodes to the graph
addNodes(Array.from({ length: 10 }, generateRandomNode))
}
</script>
<template>
<VueFlow :nodes="initialNodes">
<Panel>
<button type="button" @click="onAddNode">Add a node</button>
<button type="button" @click="onAddNodes">Add multiple nodes</button>
</Panel>
</VueFlow>
</template>
信息
如果你想要双向绑定节点,请使用 v-model:nodes="nodes"
。这将允许你修改节点并将更改反映在图表中。
¥If you want to have two-way binding of nodes, use v-model:nodes="nodes"
. This will allow you to mutate your nodes and have the changes reflected in the graph.
从图形中移除节点
¥Removing Nodes from the Graph
与添加节点类似,可以通过从 Vue Flow 组件的 mode-value
(使用 v-model
)或 nodes
属性中移除节点来从图中移除它们。
¥Similar to adding nodes, nodes can be removed from the graph by removing them from the mode-value
(using v-model
) or from the nodes
prop of the Vue Flow component.
vue
<script setup>
import { ref } from 'vue'
import { VueFlow, Panel } from '@vue-flow/core'
const nodes = ref([
{
id: '1',
position: { x: 50, y: 50 },
data: { label: 'Node 1' },
},
{
id: '2',
position: { x: 150, y: 50 },
data: { label: 'Node 2' },
}
])
function removeNode(id) {
nodes.value = nodes.value.filter((node) => node.id !== id)
}
</script>
<template>
<VueFlow :nodes="nodes">
<Panel>
<button type="button" @click="removeNode('1')">Remove Node 1</button>
<button type="button" @click="removeNode('2')">Remove Node 2</button>
</Panel>
</VueFlow>
</template>
removeNodes
操作可通过 useVueFlow 获得,允许你直接从状态中删除节点。
¥The removeNodes
action is available through useVueFlow, allowing you to remove nodes straight from the state.
你还可以在渲染图表的组件外部使用此操作,例如在侧边栏或工具栏中。
¥You can also use this action outside the component rendering the graph, like in a Sidebar or Toolbar.
vue
<script setup>
import { ref } from 'vue'
import { VueFlow, Panel, useVueFlow } from '@vue-flow/core'
const initialNodes = ref([
{
id: '1',
position: { x: 50, y: 50 },
data: { label: 'Node 1' },
},
{
id: '2',
position: { x: 150, y: 50 },
data: { label: 'Node 2' },
}
])
const { removeNodes } = useVueFlow()
function removeOneNode() {
removeNodes('1')
}
function removeMultipleNodes() {
removeNodes(['1', '2'])
}
</script>
<template>
<VueFlow :nodes="initialNodes">
<Panel>
<button type="button" @click="removeOneNode">Remove Node 1</button>
<button type="button" @click="removeMultipleNodes">Remove Node 1 and 2</button>
</Panel>
</VueFlow>
</template>
更新节点数据
¥Updating Node Data
由于节点是响应式对象,你可以随时通过简单地改变它来更新它们的数据。这允许你随时禁用或启用句柄、更改标签,甚至向数据对象添加新属性。
¥Since nodes are reactive object, you can update their data at any point by simply mutating it. This allows you to disable or enable handles, change the label, or even add new properties to the data object at any point in time.
实现此目的的方法有很多,以下是一些示例:
¥There are multiple ways of achieving this, here are some examples:
ts
import { useVueFlow } from '@vue-flow/core'
const instance = useVueFlow()
// use the `updateNodeData` method to update the data of an edge
instance.updateNodeData(edgeId, { hello: 'mona' })
// find the node in the state by its id
const node = instance.findNode(nodeId)
node.data = {
...node.data,
hello: 'world',
}
// you can also mutate properties like `selectable` or `draggable`
node.selectable = false
node.draggable = false
// or use `updateNode` to update the node directly
instance.updateNode(nodeId, { selectable: false, draggable: false })
vue
<!-- CustomNode.vue -->
<script setup>
import { useNode } from '@vue-flow/core'
// `useNode` returns us the node object straight from the state
// since the node obj is reactive, we can mutate it to update our nodes' data
const { node } = useNode()
function onSomeEvent() {
node.data = {
...node.data,
hello: 'world',
}
// you can also mutate properties like `selectable` or `draggable`
node.selectable = false
node.draggable = false
}
</script>
vue
<script setup>
import { ref } from 'vue'
const nodes = ref([
{
id: '1',
position: { x: 50, y: 50 },
data: {
label: 'Node 1',
hello: 'world',
}
},
])
function onSomeEvent(nodeId) {
const node = nodes.value.find((node) => node.id === nodeId)
node.data = {
...nodes.value[0].data,
hello: 'world',
}
// you can also mutate properties like `selectable` or `draggable`
node.selectable = false
node.draggable = false
}
</script>
<template>
<VueFlow :nodes="nodes">
<Panel>
<button type="button" @click="onSomeEvent('1')">Update Node 1</button>
</Panel>
</VueFlow>
</template>
预定义节点类型
Vue Flow 提供多种内置节点类型,你可以立即使用。包含的节点类型为 default
、input
和 output
。
¥Vue Flow provides several built-in node types that you can leverage immediately. The included node types are default
, input
, and output
.
默认节点
¥Default Node
默认节点包含两个句柄,用作地图中的分支连接点。
¥A default node includes two handles and serves as a branching junction in your map.
你可以自由地在节点定义中确定句柄的位置。
¥You have the freedom to determine the location of handles in the node's definition.
ts
import { ref } from 'vue'
import { Position } from '@vue-flow/core'
const nodes = ref([
{
id: '1',
type: 'default', // You can omit this as it's the fallback type
targetPosition: Position.Top, // or Bottom, Left, Right,
sourcePosition: Position.Bottom, // or Top, Left, Right,
data: { label: 'Default Node' },
}
])
输入节点
¥Input Node
输入节点只有一个句柄,默认位于底部。它代表地图的起点。
¥An input node features a single handle, which is by default positioned at the bottom. It represents a starting point of your map.
ts
import { ref } from 'vue'
import { Position } from '@vue-flow/core'
const nodes = ref([
{
id: '1',
type: 'input',
sourcePosition: Position.Bottom, // or Top, Left, Right,
data: { label: 'Input Node' },
}
])
输出节点
¥Output Node
输出节点也拥有一个句柄,尽管它通常位于顶部。此节点表示地图的结束点。
¥An output node also possesses a single handle, although it is typically found at the top. This node represents a conclusion point of your map.
ts
import { ref } from 'vue'
import { Position } from '@vue-flow/core'
const nodes = ref([
{
id: '1',
type: 'output',
targetPosition: Position.Top, // or Bottom, Left, Right,
data: { label: 'Output Node' },
}
])
用户定义节点
¥User-Defined Nodes
在前面提到的默认节点类型之上,你可以根据需要创建任意数量的自定义节点类型。节点类型由节点的定义决定。
¥On top of the default node types mentioned earlier, you can create as many custom node-types as you need. Node-types are determined from your nodes' definitions.
vue
<script setup>
import { ref } from 'vue'
import { VueFlow } from '@vue-flow/core'
import CustomNode from './CustomNode.vue'
import SpecialNode from './SpecialNode.vue'
export const nodes = ref([
{
id: '1',
data: { label: 'Node 1' },
// this will create the node-type `custom`
type: 'custom',
position: { x: 50, y: 50 },
},
{
id: '1',
data: { label: 'Node 1' },
// this will create the node-type `special`
type: 'special',
position: { x: 150, y: 50 },
}
])
</script>
<template>
<VueFlow :nodes="nodes">
<template #node-custom="customNodeProps">
<CustomNode v-bind="customNodeProps" />
</template>
<template #node-special="specialNodeProps">
<SpecialNode v-bind="specialNodeProps" />
</template>
</VueFlow>
</template>
vue
<script setup>
import { Position, Handle } from '@vue-flow/core'
// props were passed from the slot using `v-bind="customNodeProps"`
const props = defineProps(['label'])
</script>
<template>
<div>
<Handle type="target" :position="Position.Top" />
<div>{{ label }}</div>
<Handle type="source" :position="Position.Bottom" />
</div>
</template>
vue
<script setup lang="ts">
import { ref } from 'vue'
import type { Node } from '@vue-flow/core'
import { VueFlow } from '@vue-flow/core'
import CustomNode from './CustomNode.vue'
import SpecialNode from './SpecialNode.vue'
// You can pass 3 optional generic arguments to the Node interface, allowing you to define:
// 1. The data object type
// 2. The events object type
// 3. The possible node types
export interface CustomData {
hello: string
}
export interface CustomEvents {
onCustomEvent: (event: MouseEvent) => void
}
type CustomNodeTypes = 'custom' | 'special'
type CustomNode = Node<CustomData, CustomEvents, CustomNodeTypes>
export const nodes = ref<CustomNode[]>([
{
id: '1',
data: { label: 'Node 1' },
// this will create the node-type `custom`
type: 'custom',
position: { x: 50, y: 50 },
},
{
id: '2',
data: { label: 'Node 2' },
// this will create the node-type `special`
type: 'special',
position: { x: 150, y: 50 },
},
{
id: '3',
data: { label: 'Node 3' },
// 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
type: 'invalid',
position: { x: 150, y: 50 },
}
])
</script>
<template>
<VueFlow :nodes="nodes">
<template #node-custom="customNodeProps">
<CustomNode v-bind="customNodeProps" />
</template>
<template #node-special="specialNodeProps">
<SpecialNode v-bind="specialNodeProps" />
</template>
</VueFlow>
</template>
vue
<script setup lang="ts">
import type { NodeProps } from '@vue-flow/core'
import { Position } from '@vue-flow/core'
import { CustomData, CustomEvents } from './nodes'
// props were passed from the slot using `v-bind="customNodeProps"`
const props = defineProps<NodeProps<CustomData, CustomEvents>>()
console.log(props.data.hello) // 'world'
</script>
<template>
<div>
<Handle type="target" :position="Position.Top" />
<div>{{ label }}</div>
<Handle type="source" :position="Position.Bottom" />
</div>
</template>
然后,Vue Flow 将尝试将此节点类型解析为组件。优先考虑状态的 nodeTypes 对象中的定义。接下来,它会尝试将该组件与全局注册的同名组件进行匹配。最后,它会搜索提供的模板插槽来填充节点类型。
¥Vue Flow will then attempt to resolve this node-type to a component. Priority is given to a definition in the nodeTypes 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 node-type.
如果在解析组件时没有任何方法产生结果,则使用默认节点类型作为后备。
¥If no methods produce a result in resolving the component, the default node-type is used as a fallback.
模板插槽
¥Template slots
定义自定义节点最简单的方法之一是将它们作为模板插槽传递。针对用户定义的节点类型,已完成对插槽名称的动态解析,这意味着类型为 custom
的节点预计会有一个名为 #node-custom
的插槽。
¥One of the easiest ways to define custom nodes is, by passing them as template slots. Dynamic resolution to slot-names is done for your user-defined node-types, meaning a node with the type custom
is expected to have a slot named #node-custom
.
vue
<script setup>
import { VueFlow } from '@vue-flow/core'
import CustomNode from './CustomNode.vue'
const nodes = ref([
{
id: '1',
data: { label: 'Node 1' },
type: 'custom',
position: { x: 50, y: 50 },
}
])
</script>
<template>
<VueFlow :nodes="nodes">
<!-- the expected slot name is `node-custom` -->
<template #node-custom="props">
<CustomNode v-bind="props" />
</template>
</VueFlow>
</template>
节点类型对象
¥Node-types object
或者,也可以通过将对象作为 prop 传递给 VueFlow 组件(或作为可组合项的选项)来定义节点类型。
¥Alternatively, node-types can also be defined by passing an object as a prop to the VueFlow component (or as an option to the composable).
警告
请谨慎地将你的组件标记为原始(使用 Vue 库中的 marked 函数),以防止它们转换为响应式对象。否则,Vue 将在控制台上显示警告。
¥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.
vue
<script setup>
import { markRaw } from 'vue'
import CustomNode from './CustomNode.vue'
import SpecialNode from './SpecialNode.vue'
const nodeTypes = {
custom: markRaw(CustomNode),
special: markRaw(SpecialNode),
}
const nodes = ref([
{
id: '1',
data: { label: 'Node 1' },
type: 'custom',
},
{
id: '1',
data: { label: 'Node 1' },
type: 'special',
}
])
</script>
<template>
<VueFlow :nodes="nodes" :nodeTypes="nodeTypes" />
</template>
```
::: tip
[You can find a working example here](/examples/nodes/).
:::
## [Node Props](/typedocs/interfaces/NodeProps)
Your custom nodes are enclosed so that fundamental functions like dragging or selecting operate.
But you may wish to expand on these features or implement your business logic inside nodes, thus your nodes receive the following properties:
| Prop Name | Description | Type | Optional |
|-------------------------------------------------------------|---------------------------------------------------------------------|------------------------------------------------------------|--------------------------------------------|
| id | Unique node id | string | <Close class="text-red-500" /> |
| type | Node Type | string | <Close class="text-red-500" /> |
| selected | Is node selected | boolean | <Close class="text-red-500" /> |
| connectable | Can node handles be connected | [HandleConnectable](/typedocs/type-aliases/HandleConnectable) | <Close class="text-red-500" /> |
| position | Node's x, y (relative) position on the graph | [XYPosition](/typedocs/interfaces/XYPosition) | <Close class="text-red-500" /> |
| dimensions | Dom element dimensions (width, height) | [Dimensions](/typedocs/interfaces/Dimensions) | <Close class="text-red-500" /> |
| label | Node label, either a string or a VNode. `h('div', props, children)` | string \| VNode \| Component \| Object | <Check class="text-[var(--vp-c-brand)]" /> |
| isValidTargetPos <Badge type="warning" text="deprecated" /> | Called when used as target for new connection | [ValidConnectionFunc](/typedocs/type-aliases/ValidConnectionFunc) | <Check class="text-[var(--vp-c-brand)]" /> |
| isValidSourcePos <Badge type="warning" text="deprecated" /> | Called when used as the source for a new connection | [ValidConnectionFunc](/typedocs/type-aliases/ValidConnectionFunc) | <Check class="text-[var(--vp-c-brand)]" /> |
| parent | Parent node id | string | <Check class="text-[var(--vp-c-brand)]" /> |
| dragging | Is node currently dragging | boolean | <Close class="text-red-500" /> |
| resizing | Is node currently resizing | boolean | <Close class="text-red-500" /> |
| zIndex | Node z-index | number | <Close class="text-red-500" /> |
| targetPosition | Handle position | [Position](/typedocs/enumerations/Position) | <Check class="text-[var(--vp-c-brand)]" /> |
| sourcePosition | Handle position | [Position](/typedocs/enumerations/Position) | <Check class="text-[var(--vp-c-brand)]" /> |
| dragHandle | Drag handle query selector | string | <Check class="text-[var(--vp-c-brand)]" /> |
| data | Additional data of node | any object | <Close class="text-red-500" /> |
| events | Contextual and custom events of node | [NodeEventsOn](/typedocs/type-aliases/NodeEventsOn) | <Close class="text-red-500" /> |
## [Node Events](/typedocs/type-aliases/NodeEventsHandler)
Vue Flow provides two main ways of listening to node events,
either by using `useVueFlow` to bind listeners to the event handlers or by binding them to the `<VueFlow>` component.
::: code-group
```vue [useVueFlow]
<script setup>
import { ref } from 'vue'
import { VueFlow, useVueFlow } from '@vue-flow/core'
// useVueFlow provides access to the event handlers
const {
onNodeDragStart,
onNodeDrag,
onNodeDragStop,
onNodeClick,
onNodeDoubleClick,
onNodeContextMenu,
onNodeMouseEnter,
onNodeMouseLeave,
onNodeMouseMove
} = useVueFlow()
const nodes = ref([
{
id: '1',
data: { label: 'Node 1' },
position: { x: 50, y: 50 },
},
])
// bind listeners to the event handlers
onNodeDragStart((event) => {
console.log('Node drag started', event)
})
onNodeDrag((event) => {
console.log('Node dragged', event)
})
onNodeDragStop((event) => {
console.log('Node drag stopped', event)
})
// ... and so on
</script>
<template>
<VueFlow :nodes="nodes" />
</template>
```
```vue [component]
<script setup>
import { ref } from 'vue'
import { VueFlow } from '@vue-flow/core'
const nodes = ref([
{
id: '1',
data: { label: 'Node 1' },
position: { x: 50, y: 50 },
},
])
function logEvent(name, data) {
console.log(name, data)
}
</script>
<template>
<!-- bind listeners to the event handlers -->
<VueFlow
:nodes="nodes"
@node-drag-start="logEvent('drag start', $event)"
@node-drag="logEvent('drag', $event)"
@node-drag-stop="logEvent('drag stop', $event)"
@node-click="logEvent('click', $event)"
@node-double-click="logEvent('dblclick', $event)"
@node-contextmenu="logEvent('contextmenu', $event)"
@node-mouse-enter="logEvent('mouseenter', $event)"
@node-mouse-leave="logEvent('mouseleave', $event)"
@node-mouse-move="logEvent('mousemove', $event)"
/>
</template>
```
:::
<div class="mt-4 bg-[var(--vp-code-block-bg)] rounded-lg h-50">
<VueFlow
v-model="defaultNode"
@node-drag-start="logEvent('drag start', $event)"
@node-drag="logEvent('drag', $event)"
@node-drag-stop="logEvent('drag stop', $event)"
@node-click="logEvent('click', $event)"
@node-double-click="logEvent('dblclick', $event)"
@node-contextmenu="logEvent('contextmenu', $event)"
@node-mouse-enter="logEvent('mouseenter', $event)"
@node-mouse-leave="logEvent('mouseleave', $event)"
@node-mouse-move="logEvent('mousemove', $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).
:::
### User-Defined Nodes
When constructing a new node type, it's necessary for you to add some styling specific to it.
User-created nodes don't have any default styles associated and thus need custom styling.
```css
.vue-flow__node-custom {
background: #9CA8B3;
color: #fff;
padding: 10px;
}
在节点内实现滚动
¥Implementing Scrolling within Nodes
有时,节点可能包含大量内容,用户如果没有滚动功能,很难查看所有内容。为了在不调用节点缩放或平移行为的情况下实现滚动功能,Vue Flow 提供了 noWheelClassName
属性。
¥Sometimes, a node might contain a large amount of content, making it difficult for users to view everything without the aid of a scroll function. To facilitate this scrolling ability without invoking zoom or pan behaviors on the node, Vue Flow provides the noWheelClassName
property.
noWheelClassName
属性允许你指定一个类名,当应用于节点时,将禁用该特定节点上的默认滚动缩放或滚动平移事件。
¥The noWheelClassName
property allows you to specify a class name that, when applied to a node, will disable the default zoom-on-scroll or pan-on-scroll events on that particular node.
默认情况下,noWheelClassName
是 nowheel
。
¥By default, the noWheelClassName
is nowheel
.
vue
<script setup>
import { ref } from 'vue'
const listItems = ref(Array.from({ length: 100 }, (_, i) => i))
</script>
<template>
<div class="custom-node-container">
<ul class="nowheel">
<li v-for="item in listItems" :key="item">Item {{ item }}</li>
</ul>
</div>
</template>
防止节点内拖拽行为
¥Preventing Drag Behavior withing Nodes
在某些情况下,你可能需要与节点内容进行交互,但不触发节点本身的拖动操作。当节点包含你希望用户使用的交互元素(例如输入框、按钮或滑块)时,这会特别有用。
¥There are certain scenarios where you might need to interact with the contents of a node without triggering a drag action on the node itself. This can be particularly useful when nodes contain interactive elements like input boxes, buttons, or sliders that you want your users to engage with.
为了实现这一点,Vue Flow 提供了一个 noDragClassName
属性。此属性允许指定类名,当应用于节点内的元素时,可防止在用户与该元素交互时触发节点上的拖动操作。
¥To accomplish this, Vue Flow provides a noDragClassName
property. This property allows specification of a class name, which when applied to an element within a node, prevents triggering a drag action on the node when the user interacts with that element.
默认情况下,noDragClassName
设置为 nodrag
。
¥By default, the noDragClassName
is set as nodrag
.
vue
<script setup>
import { ref } from 'vue'
const inputValue = ref('')
</script>
<template>
<div class="custom-node-container">
<input class="nodrag" v-model="inputValue" />
</div>
</template>