这周接了个小外包,要求用vue实现如下图的拖拽效果
原理
@mousedown
监听鼠标按下,按下后开启mousemove + mouseup
监听器,并根据clientY + offsetTop
计算出元素新的top高度进行赋值,实现元素跟随。具体源码如下
<div title="demo" class="icon" @mousedown="demo">
<img src="../assets/logo.png" alt="">
<div class="icon_title" :style="{display: state.isShow ? 'block' : 'none'}">
拖拽下拉新增书签 <br /> 拖回顶部删除书签
</div>
</div>
demo(e) {
//去除默认样式 - 避免拖动元素出现禁止图标
e.preventDefault && e.preventDefault();
//获取目标元素
let odiv = e.target;
//算出鼠标相对元素的位置
let disY = e.clientY - odiv.offsetTop;
let item = {
top: 0,
id: 1,
url: '/src/assets/logo.png'
}
//监听鼠标移动事件
document.onmousemove = (e) => {
//用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
let top = e.clientY - disY;
//重新赋值
item.top = top;
};
//监听鼠标松开
document.onmouseup = (e) => {
document.onmousemove = null;
document.onmouseup = null;
//赋值
this.itemLeft.push(item)
};
},
参考链接:另一个Vue拖拽的学习参考链接:关于clientY等参数的具体计算
困难
- 鼠标按下后移动,会进入元素拖动事件并出现鼠标禁止图标。这会打断
mousemove
的监听效果。搜了半天,都说在html写个 dragglable=“true” 属性就行,然并卵。最终是在js里一行代码实现了。
//去除默认样式 - 避免拖动元素出现禁止图标
e.preventDefault && e.preventDefault();
- 按下时元素要跟随鼠标,这就需要计算鼠标在按下时相对元素的位置,移动时重赋值时也需要计算上这个相对位置。这并不是一件很好理解的事情,让我绕了好久,还是看上文的参考链接学会的。
本文只是实现拖拽功能,记录一下,希望日后再面对相似需求时可以做到炉火纯青。