1、在src文件目录下创建directives文件夹并创建index.js文件
2、编写自定义指令代码,最重要的三个点在于监听鼠标的点击事件
(1)鼠标点下事件,用于记录当前鼠标点击的位置信息以及盒子的位置信息
(2)鼠标移动事件,用于获取盒子移动的距离
(3)鼠标抬起事件,用于恢复状态以及进行边界的判断
el.addEventListener('mousedown', handleMouseDown);
el.addEventListener('mousemove', handleMouseMove);
el.addEventListener('mouseup', handleMouseUp);
export default {
install(app) {
app.directive('drag', {
created(el) {
el.style.position = 'absolute';
el.style.cursor = 'move';
},
mounted(el) {
let isMouseDown = false;
let startX = 0;
let startY = 0;
let boxPosition = { left: 0, top: 0 };
const handleMouseDown = (e) => {
isMouseDown = true;
startX = e.clientX;
startY = e.clientY;
boxPosition = { left: el.offsetLeft, top: el.offsetTop };
};
const handleMouseMove = (e) => {
if (isMouseDown) {
const moveX = e.clientX - startX;
const moveY = e.clientY - startY;
el.style.left = `${boxPosition.left + moveX}px`;
el.style.top = `${boxPosition.top + moveY}px`;
}
};
const handleMouseUp = () => {
isMouseDown = false;
el.style.transition = 'all 0.2s ease-in-out';
// 检查边界函数,用于确保元素在拖动过程中不会超出指定的边界
const checkBoundary = (property, offset, max) => {
if (offset < 0) {
el.style[property] = '0px';
} else if (offset + el.offsetWidth > max) {
el.style[property] = `${max - el.offsetWidth}px`;
}
};
checkBoundary('left', el.offsetLeft, window.innerWidth);
checkBoundary('top', el.offsetTop, window.innerHeight);
setTimeout(() => {
el.style.transition = 'none';
}, 200);
};
el.addEventListener('mousedown', handleMouseDown);
el.addEventListener('mousemove', handleMouseMove);
el.addEventListener('mouseup', handleMouseUp);
// 错误处理机制
el.addEventListener('error', (e) => {
console.error('An error occurred:', e);
});
},
unmounted(el) {
el.removeEventListener('mousedown', handleMouseDown);
el.removeEventListener('mousemove', handleMouseMove);
el.removeEventListener('mouseup', handleMouseUp);
}
});
}
}
3、在main.js中引入自定义指令并注册