hookehuyr

自定义拖拽功能

......@@ -95,6 +95,11 @@ const router = createRouter({
name: 'adv-dnd-panel',
component: () => import('../views/adv-dnd-panel/index.vue')
},
{
path: '/adv-dnd-panel-custom',
name: 'adv-dnd-panel-custom',
component: () => import('../views/adv-dnd-panel/custom.vue')
},
]
})
......
<!--
* @Date: 2025-03-10 16:52:35
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-03-13 18:28:05
* @FilePath: /logic-flow2/src/views/adv-dnd-panel/custom.vue
* @Description: 自定义拖拽功能
-->
<template>
<div class="container">
<div ref="container" class="flow-container"></div>
<div style="position: absolute; bottom: 20%; left: 50%; transform: translateX(-50%)">
<el-popover placement="top" :width="400" :visible="visible">
<template #reference>
<el-button style="margin-right: 16px" @mouseover="visible = true"
>hover</el-button
>
</template>
<div style="padding: 10px 0">
<div class="node-panel">
<div
class="node-item"
draggable="true"
@dragstart="handleDragStart($event, { type: 'rect' })"
>
矩形节点
</div>
<div
class="node-item"
draggable="true"
@dragstart="handleDragStart($event, { type: 'circle' })"
>
圆形节点
</div>
</div>
</div>
</el-popover>
</div>
</div>
</template>
<script setup>
import LogicFlow from "@logicflow/core";
const container = ref(null);
let lf = null;
const visible = ref(false);
// 拖拽事件处理函数
const handleDragStart = (e, node) => {
e.dataTransfer.setData("node", JSON.stringify(node));
};
const handleDragOver = (e) => {
e.preventDefault();
};
const handleDrop = (e) => {
e.preventDefault();
const data = JSON.parse(e.dataTransfer.getData("node"));
const canvasPoint = lf.getPointByClient(e.clientX, e.clientY);
lf.addNode({
type: data.type,
x: canvasPoint.canvasOverlayPosition.x,
y: canvasPoint.canvasOverlayPosition.y,
});
};
// 点击事件处理函数
const handleClickOutside = (e) => {
const popover = document.querySelector(".el-popover");
const button = document.querySelector(".el-button");
if (popover && button && !popover.contains(e.target) && !button.contains(e.target)) {
visible.value = false;
}
};
onMounted(() => {
lf = new LogicFlow({
container: container.value,
grid: true,
});
// 添加事件监听
container.value.addEventListener("dragover", handleDragOver);
container.value.addEventListener("drop", handleDrop);
// 添加点击事件监听
document.addEventListener("click", handleClickOutside);
lf.render({
nodes: [
{ id: "node1", type: "rect", x: 200, y: 100 },
{ id: "node2", type: "circle", x: 400, y: 100 },
],
edges: [{ id: "edge1", sourceNodeId: "node1", targetNodeId: "node2" }],
});
});
// 组件卸载时移除事件监听
onUnmounted(() => {
if (container.value) {
container.value.removeEventListener("dragover", handleDragOver);
container.value.removeEventListener("drop", handleDrop);
document.removeEventListener("click", handleClickOutside);
}
});
</script>
<style scoped>
.container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
}
.flow-container {
flex: 1;
width: 100%;
height: 100%;
}
.node-panel {
display: flex;
gap: 16px;
}
.node-item {
padding: 8px 16px;
border: 1px solid #dcdfe6;
border-radius: 4px;
cursor: grab; /* 修改这里 */
background: #fff;
&:hover {
border-color: #409eff;
color: #409eff;
}
/* 添加拖动时的样式 */
&:active {
cursor: grabbing;
}
}
</style>
<!--
* @Date: 2025-03-10 14:37:31
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-03-13 17:25:44
* @LastEditTime: 2025-03-13 17:45:28
* @FilePath: /logic-flow2/src/views/home.vue
* @Description: 文件描述
-->
......@@ -23,6 +23,7 @@
<el-button type="primary" @click="goTo('adv-edge-animation')">adv-edge-animation</el-button>
<el-button type="primary" @click="goTo('adv-menu')">adv-menu</el-button>
<el-button type="primary" @click="goTo('adv-dnd-panel')">adv-dnd-panel</el-button>
<el-button type="primary" @click="goTo('adv-dnd-panel-custom')">adv-dnd-panel-custom</el-button>
</template>
<script setup>
......