基于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>
相关推荐
春蕾夏荷_72829772521 分钟前
qt ElaWidgetTools第一个实例
开发语言·qt
lizz311 小时前
从 JUnit 深入理解 Java 注解与反射机制
java·开发语言·junit
编啊编程啊程4 小时前
JUC之AQS
java·开发语言·jvm·c++·kafka
盛夏绽放5 小时前
jQuery 知识点复习总览
前端·javascript·jquery
大怪v8 小时前
超赞👍!优秀前端佬的电子布洛芬技术网站!
前端·javascript·vue.js
好学且牛逼的马8 小时前
GOLANG 接口
开发语言·golang
ahauedu8 小时前
AI资深 Java 研发专家系统解析Java 中常见的 Queue实现类
java·开发语言·中间件
韭菜钟8 小时前
在Qt中用cmake实现类似pri文件的功能
开发语言·qt·系统架构
项目題供诗8 小时前
React学习(十二)
javascript·学习·react.js
闲人编程8 小时前
Python第三方库IPFS-API使用详解:构建去中心化应用的完整指南
开发语言·python·去中心化·内存·寻址·存储·ipfs