在 Vue.js 中,自定义指令可以用于实现元素的拖拽功能,进而实现弹窗的拖拽。以下是一个详细的实现步骤与示例代码,展示如何通过 Vue 自定义指令实现弹窗的拖拽功能。
前提
在开始之前你需要了解以下知识:
- 鼠标事件:mousemove、mousedown、mouseup
- 元素位置信息、宽高信息
- vue自定义指令
步骤 1:创建自定义指令
我们将通过 Vue 的自定义指令来实现拖拽功能。首先,定义一个全局指令 v-drag,该指令将实现元素的拖拽逻辑。
// 1.创建index.js文件来存放指令
export default {
install(app) {
app.directive("drag", {
created(el) {
el.style.position = "absolute";
el.style.cursor = "move";
},
mounted(el) {
/**
* 1. 记录鼠标点击的位置信息
* 2. 记录原始的盒子的位置信息
* 3. 计算鼠标移动的距离
*/
let isDown = false; // 是否按下鼠标
let baseX = 0, baseY = 0; // 记录鼠标初始位置
const originalInfo = {};// 记录盒子原始位置
// 给盒子绑定鼠标事件
el.addEventListener('mousedown', function (e) {
isDown = true;
baseX = e.clientX;
baseY = e.clientY;
originalInfo.left = el.offsetLeft;
originalInfo.top = el.offsetTop;
});
el.addEventListener('mousemove', function (e) {
if(isDown) {
const moveX = e.clientX - baseX;
const moveY = e.clientY - baseY;
el.style.left = moveX + originalInfo.left + 'px';
el.style.top = moveY + originalInfo.top + 'px';
}
});
el.addEventListener('mouseup', function (e) {
isDown = false;
el.style.transition = "all 0.2s ease";
// 边界处理,使弹窗始终保持在页面之内
if (el.offsetLeft > window.innerWidth - el.offsetWidth) {
el.style.left = window.innerWidth - el.offsetWidth + "px";
}
if (el.offsetLeft < 0) {
el.style.left = 0 + "px";
}
if (el.offsetTop > window.innerHeight - el.offsetHeight) {
el.style.top = window.innerHeight - el.offsetHeight + "px";
}
if (el.offsetTop < 0) {
el.style.top = 0 + "px";
}
setTimeout(() => {
el.style.transition = '';
},300)
});
}
});
}
};
通过 Vue 的自定义指令,在页面中只需要按需添加v-drag指令就可以轻松实现元素拖拽。这种方法解耦了拖拽逻辑与业务逻辑,使得代码结构更加清晰和可复用。