#### Node 節點方塊
* 節點方塊物件資料須帶有uuid和x,y 位置(提供套件svg繪圖用)
```
const elements = ref([
{
id: '1',
position: { x: 50, y: 50 },
label: 'Node 1',
}
]);
```
* 節點新增可使用套件提供的addNodes()方法產生,像是自動化劇本在拖拉和判斷才產生畫面上節點
```
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())
}
```
* 節點移除可以直接對原始node資料進行pop()等方法移除,或者使用特套件提供的removeNodes方法,利用node uuid進行移除
```
function onRemoveNodes() {
removeNodes(['1', '2'])
}
```
#### 節點更新和options設置
https://vueflow.dev/guide/node.html#updating-node-data
設定節點可不可以拖拉或固定,每一個節點都有設定options參數
```
elements.value.forEach((node) => {
node.selectable = false
node.draggable = false
})
```
#### 連接節點類型
type有default、input和output 3種,可以限制上下連結點
```
import { ref } from 'vue'
import { Position } from '@vue-flow/core'
const nodes = ref([
{
id: '1',
label: 'Default Node',
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,
}
])
```
#### User定義客製化custom node樣式(slot template)
https://vueflow.dev/examples/nodes/
slot 插槽名稱會以#node-xxxx 對應到node物件資料中的type名稱。
```
const nodes = ref([
{
id: '1',
type: 'color-selector',
data: { color: presets.ayame },
position: { x: 0, y: 50 },
},
{
id: '2',
type: 'output',
position: { x: 350, y: 114 },
targetPosition: Position.Left,
},
])
<template>
<VueFlow
v-model:nodes="nodes"
:edges="edges"
class="custom-node-flow"
:class="[colorSelectorData?.isGradient ? 'animated-bg-gradient' : '']"
:style="{ backgroundColor: colorSelectorData?.color }"
:default-viewport="{ zoom: 1.5 }"
fit-view-on-init
>
<template #node-color-selector="{ id }">
<ColorSelectorNode :id="id" />
</template>
<template #node-output>
<OutputNode />
</template>
<MiniMap :node-stroke-color="nodeStroke" :node-color="nodeColor" />
</VueFlow>
</template>
```
https://vueflow.dev/guide/node.html#user-defined-nodes
https://vueflow.dev/examples/nodes/ 調色盤案例
自訂節點槽內容- ex自動化據本是icon+文字
* 在調色盤案例中,有許多顏色的小調色icon,使用者點擊時會更換背景色,關鍵點在於點擊後呼叫原始useFlow方法,能去更動整個node物件資料,帶動外層父元件背景色資料替換。
* 去觀察ColorSelectorNode.vue檔案,利用useFlow去連接VueFlow組件的資料更新
```
const { updateNodeData } = useVueFlow() // flow update到全局物件
function onSelect(color) {
updateNodeData(props.id, { color, isGradient: false })
} // 按到時呼叫
```
#### Node 事件
https://vueflow.dev/guide/node.html#node-events
有時候需要針對使用者正在拖拉、放進去的動作進行節點判斷等邏輯,就需要用vue flow event事件去定義。
```
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 elements = ref([
{
id: '1',
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)
})
```
https://vueflow.dev/guide/composables.html
#### controlled flow 節點驗證
https://vueflow.dev/guide/controlled-flow.html#onnodeschange-onedgeschange-events
* 當節點或連接線資料有異動時,也有對應監聽事件onNodeChange、onEdgeChange,也可以將資料驗證邏輯寫在這
#### 連接線(Edge)
連接線又名邊緣,是連結節點進而形成flow chart圖表。
https://vueflow.dev/guide/edge.html#adding-edges-to-the-graph
* 基礎添加連接線可以直接在原始節點node物件,增加source/target資料形成連結接線
* 使用 addEdges方法 進行新增
* 使用 reomveEdge方法 進行連接線刪除
* **連接線uuid建議使用 e1-2 以e為開頭和一般節點區分開**
```
const { addEdges } = useVueFlow()
onMounted(() => {
// add an edge after mount
addEdges([
{
source: '1',
target: '2',
// if a node has multiple handles of the same type,
// you should specify which handle to use by id
sourceHandle: null,
targetHandle: null,
}
])
})
```
#### 連接線類型(直線、階梯線、平滑等)
https://vueflow.dev/guide/edge.html#predefined-edge-types
edges type資料形態中設定
```
export const edges = ref([
{
id: 'e1-2',
source: '1',
target: '2',
// this will create the edge-type `custom`
type: 'custom',
},
{
id: 'e1-3',
source: '1',
target: '3',
// this will create the edge-type `special`
type: 'special',
}
])
```
#### 將外部node樣板拖拉進入vue flow流程圖
https://vueflow.dev/examples/dnd.html
* 需要自己製作一個拖拉功能 useDragAndDrop()
```
const state = {
/**
* The type of the node being dragged.
*/
draggedType: ref(null), // 辦別拖拉元件類別
isDragOver: ref(false), // 拖拉完成
isDragging: ref(false), // 正在拖拉
}
// 引入useVueFlow拖拉事件
const { addNodes, screenToFlowCoordinate, onNodesInitialized, updateNode } = useVueFlow()
// 監聽使用者是否再拖拉 會傳入拖拉元素本身的DOM
watch(isDragging, (dragging) => {
// 設定拖拉時BODY元素不能選取
document.body.style.userSelect = dragging ? 'none' : ''
})
// 用原生JS將選取元素掛上drag Event
function onDragStart(event, type) {
if (event.dataTransfer) {
event.dataTransfer.setData('application/vueflow', type)
event.dataTransfer.effectAllowed = 'move'
}
draggedType.value = type
isDragging.value = true
document.addEventListener('drop', onDragEnd)
}
```
*