如何使用vue自定义指令实现弹窗拖拽

279 阅读1分钟

在 Vue.js 中,自定义指令可以用于实现元素的拖拽功能,进而实现弹窗的拖拽。以下是一个详细的实现步骤与示例代码,展示如何通过 Vue 自定义指令实现弹窗的拖拽功能。

前提

在开始之前你需要了解以下知识:

  1. 鼠标事件:mousemove、mousedown、mouseup
  2. 元素位置信息、宽高信息
  3. 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指令就可以轻松实现元素拖拽。这种方法解耦了拖拽逻辑与业务逻辑,使得代码结构更加清晰和可复用。