#### 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) } ``` *