元素拖拽?一个vue指令搞定
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
·
说在前面
🎈元素拖拽功能大家应该都不陌生了吧,今天我们一起来看看怎么编写一个
vue指令来实现元素拖拽功能吧!
效果展示

体验地址
http://jyeontu.xyz/jvuewheel/#/JDragView
实现思路
1、初始化
let startX,
startY,
currentX = 0,
currentY = 0;
el.style.position = "relative";
el.parentNode.style.position = "relative";
el.style.cursor = "pointer";
- (1)指令钩子函数 inserted:当被绑定的元素被插入到 DOM 中时,该函数被调用。
- (2)初始化变量:
- startX 和 startY 用于存储鼠标按下或触摸开始时的相对位置。
- currentX 和 currentY 用于存储元素当前的偏移量。
- (3)设置元素样式:
- el.style.position = “relative”:确保元素是相对定位的,这样移动时不会影响其他元素的布局。
- el.parentNode.style.position = “relative”:将父元素也设置为相对定位,这是为了确保子元素的定位是相对于父元素的。
- el.style.cursor = “pointer”:改变鼠标光标的样式,提供视觉反馈,表明元素可以被点击和拖动。
2、添加事件监听器
- 对于鼠标操作,添加 mousedown 和 mouseup 事件监听器。
- 对于触摸操作,添加 touchstart 和 touchend 事件监听器。
el.addEventListener("mousedown", function (event) {
event.preventDefault();
startX = event.pageX - currentX;
startY = event.pageY - currentY;
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
});
el.addEventListener("touchstart", function (event) {
event.preventDefault();
startX = event.touches[0].clientX - currentX;
startY = event.touches[0].clientY - currentY;
document.addEventListener("touchmove", onTouchMove);
document.addEventListener("touchend", onTouchEnd);
});
function onMouseUp() {
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
}
function onTouchEnd() {
document.removeEventListener("touchmove", onTouchMove);
document.removeEventListener("touchend", onTouchEnd);
}
3、事件处理函数:
- onMouseMove 和 onTouchMove:在鼠标移动或触摸移动时调用,用于更新元素的位置。
- onMouseUp 和 onTouchEnd:在鼠标松开或触摸结束时调用,用于移除 mousemove 和 touchmove 事件监听器,结束拖拽操作。
- 拖拽函数 drag:更新元素的 top 和 left 样式,使元素移动到 currentX 和 currentY 指定的位置。
function onTouchMove(event) {
event.preventDefault();
currentX = event.touches[0].clientX - startX;
currentY = event.touches[0].clientY - startY;
drag(el);
}
function onMouseMove(event) {
event.preventDefault();
currentX = event.pageX - startX;
currentY = event.pageY - startY;
drag(el);
}
function drag(el) {
el.style.top = currentY + "px";
el.style.left = currentX + "px";
}
完整代码
export default {
inserted: function (el) {
let startX,
startY,
currentX = 0,
currentY = 0;
el.style.position = "relative";
el.parentNode.style.position = "relative";
el.style.cursor = "pointer";
el.addEventListener("mousedown", function (event) {
event.preventDefault();
startX = event.pageX - currentX;
startY = event.pageY - currentY;
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
});
el.addEventListener("touchstart", function (event) {
event.preventDefault();
startX = event.touches[0].clientX - currentX;
startY = event.touches[0].clientY - currentY;
document.addEventListener("touchmove", onTouchMove);
document.addEventListener("touchend", onTouchEnd);
});
function onMouseMove(event) {
event.preventDefault();
currentX = event.pageX - startX;
currentY = event.pageY - startY;
drag(el);
}
function onMouseUp() {
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
}
function onTouchMove(event) {
event.preventDefault();
currentX = event.touches[0].clientX - startX;
currentY = event.touches[0].clientY - startY;
drag(el);
}
function onTouchEnd() {
document.removeEventListener("touchmove", onTouchMove);
document.removeEventListener("touchend", onTouchEnd);
}
function drag(el) {
el.style.top = currentY + "px";
el.style.left = currentX + "px";
}
},
};
组件库
组件文档
目前该组件也已经收录到我的组件库,组件文档地址如下:
http://jyeontu.xyz/jvuewheel/#/JThousandView
组件内容
组件库中还有许多好玩有趣的组件,如:
- 悬浮按钮
- 评论组件
- 词云
- 瀑布流照片容器
- 视频动态封面
- 3D轮播图
- web桌宠
- 贡献度面板
- 拖拽上传
- 自动补全输入框
- 图片滑块验证
等等……
组件库源码
组件库已开源到gitee,有兴趣的也可以到这里看看:https://gitee.com/zheng_yongtao/jyeontu-component-warehouse
觉得有帮助的可以点个star~
有什么问题或错误可以指出,欢迎pr~
有什么想要实现的组件或想法可以联系我~
公众号
关注公众号『前端也能这么有趣』,获取更多有趣内容。
发送『组件库』获取源码
说在后面
🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『
前端也能这么有趣』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
9e887079
[skip ci] 1 年前
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 1 年前
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)