vue3+vite实现拖拽产生连线的代码
时间: 2023-06-12 14:07:29 浏览: 160
以下是一个基于 Vue3 和 Vite 的实现拖拽产生连线的代码示例:
```html
<template>
<div class="container">
<div class="box" v-for="(item, index) in boxes" :key="item.id" :style="{ top: item.top + 'px', left: item.left + 'px' }" @mousedown="mousedown(index)">
{{ item.name }}
</div>
<svg class="line-container">
<line v-for="(line, index) in lines" :key="index" :x1="line.x1" :y1="line.y1" :x2="line.x2" :y2="line.y2" />
</svg>
</div>
</template>
<script>
import { reactive, toRefs } from 'vue'
export default {
setup() {
const state = reactive({
boxes: [
{ id: 1, name: 'Box 1', top: 100, left: 100 },
{ id: 2, name: 'Box 2', top: 200, left: 200 },
{ id: 3, name: 'Box 3', top: 300, left: 300 },
],
lines: [],
isDragging: false,
currentBoxIndex: null,
startX: null,
startY: null,
})
const mousedown = (index) => {
state.isDragging = true
state.currentBoxIndex = index
state.startX = state.boxes[index].left
state.startY = state.boxes[index].top
}
const mousemove = (event) => {
if (state.isDragging) {
const box = state.boxes[state.currentBoxIndex]
box.left = state.startX + event.clientX - state.startX - box.width / 2
box.top = state.startY + event.clientY - state.startY - box.height / 2
}
}
const mouseup = () => {
state.isDragging = false
state.currentBoxIndex = null
}
const connectBoxes = () => {
const lastBox = state.boxes[state.boxes.length - 1]
const secondLastBox = state.boxes[state.boxes.length - 2]
state.lines.push({
x1: secondLastBox.left + secondLastBox.width / 2,
y1: secondLastBox.top + secondLastBox.height / 2,
x2: lastBox.left + lastBox.width / 2,
y2: lastBox.top + lastBox.height / 2,
})
}
return {
...toRefs(state),
mousedown,
mousemove,
mouseup,
connectBoxes,
}
},
mounted() {
document.addEventListener('mousemove', this.mousemove)
document.addEventListener('mouseup', this.mouseup)
},
beforeUnmount() {
document.removeEventListener('mousemove', this.mousemove)
document.removeEventListener('mouseup', this.mouseup)
},
}
</script>
<style>
.container {
position: relative;
height: 500px;
}
.box {
position: absolute;
width: 100px;
height: 100px;
background-color: #ccc;
text-align: center;
line-height: 100px;
user-select: none;
cursor: move;
}
.line-container {
position: absolute;
width: 100%;
height: 100%;
pointer-events: none;
}
</style>
```
代码中实现了一个简单的拖拽产生连线的功能,具体实现方式如下:
1. 在模板中使用 `v-for` 渲染出多个可拖拽的方块(`<div class="box">`)和一个 SVG 容器(`<svg class="line-container">`)来绘制连线;
2. 通过 `@mousedown` 监听鼠标按下事件,记录当前拖拽的方块的索引和起始位置;
3. 通过 `@mousemove` 监听鼠标移动事件,根据当前鼠标位置计算出方块的新位置;
4. 通过 `@mouseup` 监听鼠标抬起事件,清空当前拖拽状态;
5. 通过方法 `connectBoxes` 将最后两个方块连线。
需要注意的是,代码中通过 `reactive` 创建了一个响应式对象 `state`,并使用 `toRefs` 将其转换为响应式引用,以便在模板中使用。并且,在组件的 `mounted` 和 `beforeUnmount` 钩子中分别添加和移除了全局的鼠标移动和抬起事件监听器。
阅读全文