vue 拖拽产生连线_基于Vue 撸一个指令实现拖拽功能

之前撸了一个copy 指令,这次再撸一个拖拽指令。。

具体是个什么蛇皮玩意儿呢,大概就像介样:

a1c437cece6d623e5bebc08f66ddf757.gif

emmm。。没错,看起来就是如此的鸡肋,但是莫得办法,大佬喜欢啊。

由于我们项目中用的是 element-ui ,所有这个指令只针对 element-ui 的对话框组件哈,如果你们用的别的 ui 库也有这个需求的,涂涂改改应该也能用。。

其实这个拖拽的原理还是很简单的:

1.首先鼠标按下( onmousedown )

记录目标元素当前的 left 和 top 值

2.鼠标移动( onmousemove )

计算每次移动的横向距离 ( disX ) 和纵向距离 ( disY )

并改变元素的 left ( left = left + disX )和 top ( top = top + disY )值

3.鼠标松开( onmouseup )

完成一次拖拽,做一些收尾工作

left 和 top 值容易获取,关键是 disX 和 disY 怎么计算呢?

容我先普及一哈:

clientX :表示鼠标当前的 X 坐标

clientY :表示鼠标当前的 Y 坐标

那么伪代码就是:

disX = 鼠标按下时的 clientX - 鼠标松开

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个Vue 实现拖拽产生连线的示例代码: ```html <template> <div class="container"> <div class="box" v-for="(item, index) in boxes" :key="index" :style="{ top: item.top + 'px', left: item.left + 'px' }" @mousedown="startDrag($event, item)"> <span>{{ index }}</span> </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> export default { data() { return { boxes: [ { top: 50, left: 50 }, { top: 50, left: 200 }, { top: 200, left: 50 }, { top: 200, left: 200 } ], lines: [] } }, methods: { startDrag(event, item) { const startX = event.pageX const startY = event.pageY const startTop = item.top const startLeft = item.left const moveHandler = (event) => { const deltaX = event.pageX - startX const deltaY = event.pageY - startY item.top = startTop + deltaY item.left = startLeft + deltaX } const upHandler = () => { document.removeEventListener('mousemove', moveHandler) document.removeEventListener('mouseup', upHandler) this.updateLines() } document.addEventListener('mousemove', moveHandler) document.addEventListener('mouseup', upHandler) }, updateLines() { const boxes = this.$el.querySelectorAll('.box') const lines = [] for (let i = 0; i < boxes.length; i++) { const box1 = boxes[i] const box1Rect = box1.getBoundingClientRect() for (let j = i + 1; j < boxes.length; j++) { const box2 = boxes[j] const box2Rect = box2.getBoundingClientRect() const line = { x1: box1Rect.left + box1Rect.width / 2, y1: box1Rect.top + box1Rect.height / 2, x2: box2Rect.left + box2Rect.width / 2, y2: box2Rect.top + box2Rect.height / 2 } lines.push(line) } } this.lines = lines } } } </script> <style> .container { position: relative; width: 400px; height: 400px; background-color: #f1f1f1; } .box { position: absolute; width: 50px; height: 50px; background-color: #fff; border: 1px solid #ddd; display: flex; justify-content: center; align-items: center; cursor: move; } .box span { font-size: 20px; } .line-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; } </style> ``` 这里的核心思路是,当鼠标按下时记录当前元素的位置,然后在鼠标移动时计算偏移量,从而更新元素的位置。每次更新位置时,都重新计算连线的位置。具体实现方法是,使用 `getBoundingClientRect()` 方法获取元素的位置和尺寸,然后计算两个元素的中心点坐标,从而确定连线的起点和终点坐标。最后用 SVG 的 `line` 元素来绘制连线
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值