custom.vue
3.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<!--
* @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>