基于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>
相关推荐
To_OC6 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
To_OC6 小时前
LC 17 电话号码的字母组合:我的回溯算法,就是从这道题开窍的
javascript·算法·leetcode
我是坏垠8 小时前
Crypto、Cipher与Password:Java加密开发的三个核心概念
java·开发语言·python
white_ant8 小时前
JDK LTS 版本升级迁移注意事项大全
java·开发语言
Bobolink_8 小时前
跨境业务网络环境评估,“干净、一致、独享”三个关键指标
开发语言·网络·php·跨境网络·网络环境
你怎么知道我是队长8 小时前
JavaScript的变量和数据类型介绍
开发语言·javascript·ecmascript
xingke8 小时前
C 语言多文件编程:(一)头文件、extern、编译链接
c语言·开发语言·多文件
戮漠summer9 小时前
Missing Semester 计算机教育中缺失的一课 Lecture 01 Shell
开发语言·后端·scala
jinyishu_9 小时前
C++ string使用方法
开发语言·c++
EW Frontier9 小时前
三级跳突破864维动作空间——QMIX-Hierarchical多无人机协同通信方法全解析【附python代码】
开发语言·python·无人机·强化学习·通信资源分配