在项目utils 文件下 新建 hook.ts
/**
* 这是一个自定义指令,用于实现元素的拖拽效果
* 使用方式:v-draggable
* 为了解决拖拽时结束会触发点击事件click,想只在点击时触发某一个事件,拖拽结束时不触发点击事件 可使用自定义事件 myClick
* 使用方式:v-draggable @myClick="handleClick"
*/
hook.ts
export const draggable = {
mounted(el: HTMLElement) {
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; // 鼠标点击位置
let dragging = false; // 是否正在拖拽
let wasDragging = false; // 是否拖拽过
el.onmousedown = dragMouseDown; // 按下鼠标时触发
el.onmouseup = closeDragElement; // 松开鼠标时触发
el.onclick = preventClickAfterDrag; // 点击时触发
function dragMouseDown(e: MouseEvent) {
e.preventDefault();
dragging = true;
pos3 = e.clientX;
pos4 = e.clientY;
document.onmousemove = elementDrag;
}
function elementDrag(e: MouseEvent) {
if (!dragging) return;
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
el.style.top = (el.offsetTop - pos2) + "px";
el.style.left = (el.offsetLeft - pos1) + "px";
wasDragging = true;
}
function closeDragElement() {
dragging = false;
document.onmousemove = null;
if (wasDragging) {
wasDragging = false;
} else {
el.dispatchEvent(new CustomEvent('myClick'));
}
}
function preventClickAfterDrag(e: MouseEvent) {
e.stopPropagation();
}
},
unmounted(el: HTMLElement) {
el.onmousedown = null;
el.onmouseup = null;
el.onclick = null;
}
}
文件main.ts
import { draggable } from "@/utils/hooks";
// 注册全局指令 v-draggable 拖拽
app.directive("draggable", draggable);
使用时:
使用时 直接在要拖拽的标签上
<div v-draggable>拖拽div</div>