js
复制代码
<template>
<div style="width: 100%;height: calc(100vh - 84px)">
<VueFlow :nodes="nodes" :edges="edges" @drop="onDrop" @dragover="onDragOver" @dragleave="onDragLeave">
<div class="dropzone-background">
<Background pattern-color="#aaa" :gap="8" :style="{
backgroundColor: isDragOver ? '#e7f3ff' : 'transparent',
transition: 'background-color 0.2s ease',
}">
</Background>
<div class="overlay">
<p v-if="isDragOver">Drop here</p>
</div>
</div>
</VueFlow>
<Panel position="top-right" class="process-panel">
<div class="description">You can drag these nodes to the pane.</div>
<div class="nodes">
<div class="vue-flow__node-input" :draggable="true" @dragstart="onDragStart($event, 'input')">Input Node</div>
<div class="vue-flow__node-default" :draggable="true" @dragstart="onDragStart($event, 'default')">Default Node
</div>
<div class="vue-flow__node-output" :draggable="true" @dragstart="onDragStart($event, 'output')">Output Node
</div>
</div>
</Panel>
</div>
</template>
<script setup name="Index">
import {ref} from 'vue'
import {VueFlow, Panel, useVueFlow} from '@vue-flow/core'
import {Background} from '@vue-flow/background'
import {MiniMap} from '@vue-flow/minimap'
const {onConnect, addEdges, addNodes, toObject, screenToFlowCoordinate, onNodesInitialized, updateNode} = useVueFlow()
const instance = useVueFlow()
const {proxy} = getCurrentInstance();
const nodes = ref([]);
const edges = ref([]);
const draggedType = ref(null);
const isDragOver = ref(false);
const isDragging = ref(false);
/**
* 开始拖拽选项的事件
* @param event
* @param type
*/
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)
}
/**
* 拖拽到画布vueflow的事件
* @param event
*/
function onDragOver(event) {
event.preventDefault()
if (draggedType.value) {
isDragOver.value = true
if (event.dataTransfer) {
event.dataTransfer.dropEffect = 'move'
}
}
}
/**
* 拖拽放下的事件
* @param event
*/
function onDrop(event) {
const position = screenToFlowCoordinate({
x: event.clientX,
y: event.clientY,
})
const nodeId = Math.random() + "id";
const newNode = {
id: nodeId,
type: draggedType.value,
position,
data: {label: nodeId},
}
// 更新位置到鼠标中心
const {off} = onNodesInitialized(() => {
updateNode(nodeId, (node) => ({
position: {x: node.position.x - node.dimensions.width / 2, y: node.position.y - node.dimensions.height / 2},
}))
off()
})
addNodes(newNode)
}
/**
* 拖拽到画布外面的的事件
*/
function onDragLeave() {
isDragOver.value = false
}
/**
* 拖拽结束
*/
function onDragEnd() {
isDragging.value = false
isDragOver.value = false
draggedType.value = null
document.removeEventListener('drop', onDragEnd)
}
onConnect(addEdges)
</script>
<style>
/* import the necessary styles for Vue VueFlow to work */
@import '@vue-flow/core/dist/style.css';
/* import the default theme, this is optional but generally recommended */
@import '@vue-flow/core/dist/theme-default.css';
.process-panel {
background-color: #EBEEF5;
padding: 10px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
display: flex;
flex-direction: column;
}
.dropzone-background {
position: relative;
height: 100%;
width: 100%
}
.dropzone-background .overlay {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
z-index: 1;
pointer-events: none
}
</style>