基于vueflow可拖拽元素的示例(基于官网示例的单文件示例)

效果图

代码

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>
相关推荐
blammmp12 分钟前
算法专题四:前缀和
java·开发语言·算法
www_pp_15 分钟前
# 创建一个功能完备的计算器应用:使用PyQt5和Python
开发语言·python·qt
Aimyon_3633 分钟前
Java复习笔记-基础
java·开发语言·笔记
androidwork1 小时前
Kotlin Android工程Mock数据方法总结
android·开发语言·kotlin
codefly-xtl1 小时前
责任链设计模式
java·开发语言·设计模式
非晓为骁1 小时前
【Go】优化文件下载处理:从多级复制到零拷贝流式处理
开发语言·后端·性能优化·golang·零拷贝
北极象2 小时前
Golang中集合相关的库
开发语言·后端·golang
小浪学编程2 小时前
C#学习7_面向对象:类、方法、修饰符
开发语言·学习·c#
Q_Q19632884752 小时前
python小说网站管理系统-小说阅读系统
开发语言·spring boot·python·django·flask·node.js·php
goTsHgo2 小时前
Java的对象头:原理与源码详解
java·开发语言