基于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>
相关推荐
星夜离尘567 小时前
MATLAB 工程实验:不等间隔流量积分,先把缺口与覆盖率说清楚
开发语言·matlab·时间戳·数据质量·数值积分
Ai-_Man7 小时前
Meta Muse还是不可以导出左侧所有对话,只能点进去单条内容导出,方法不对吗?
开发语言·人工智能·ai·小程序·c#·1024程序员节
梓豪csd7 小时前
消息订阅中心:谁该收到哪条通知
java·开发语言·人工智能·低代码·自动化·1024程序员节
学逆向的8 小时前
C 枚举变量
c语言·开发语言·网络安全
Sakura_j_h_8 小时前
Python 在定时任务里输出 emoji,UnicodeEncodeError 从哪来
开发语言·字符编码·windows·python·定时任务
paopaokaka_luck10 小时前
宠物门店经营管理系统(销售与库存联动、进货自动记账、 退换与退款关联、员工个人业绩、ECharts 经营分析、滞销识别与客户分层、宠物档案年龄计算)
前端·javascript·spring boot·mysql·echarts·mybatis·1024程序员节
小成2023032026513 小时前
C++~07补充
开发语言·c++
鶴哥只手遮天14 小时前
jQuery 4.0 源码架构与工程实践-第 10 章 尺寸、几何与显隐
前端·javascript·jquery
2401_8858850416 小时前
国际语音C#接口怎么写?.NET环境下实现国际语音验证码批量下发
开发语言·c#·.net