vue3自定义拖拽指令

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中引入自定义指令并注册

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值