弹窗拖拽-指令

lishihuan小于 1 分钟

弹窗拖拽-指令

创建指令

// directives/v-draggable.js
/**
 * 自定义拖拽指令
 */
export default {
  bind(el) {
    let isDragging = false;
    let startX, startY, offsetX, offsetY;

    // 在mousedown事件上开始拖拽
    el.addEventListener('mousedown', (e) => {
      isDragging = true;
      startX = e.clientX;
      startY = e.clientY;

      // 禁止文本选中,避免拖拽时出现不必要的选择效果
      document.body.style.userSelect = 'none';

      // 添加鼠标移动和鼠标抬起事件监听
      const onMouseMove = (e) => {
        if (isDragging) {
          offsetX = e.clientX - startX;
          offsetY = e.clientY - startY;

          // 更新元素位置
          el.style.left = `${el.offsetLeft + offsetX}px`;
          el.style.top = `${el.offsetTop + offsetY}px`;

          startX = e.clientX;
          startY = e.clientY;
        }
      };

      const onMouseUp = () => {
        isDragging = false;
        document.removeEventListener('mousemove', onMouseMove);
        document.removeEventListener('mouseup', onMouseUp);

        // 恢复文本选中
        document.body.style.userSelect = '';
      };

      document.addEventListener('mousemove', onMouseMove);
      document.addEventListener('mouseup', onMouseUp);
    });
  }
};

调用

  • 全局注册 (main.js

    import Vue from 'vue';
    import App from './App.vue';
    import vDraggable from './directives/v-draggable'; // 导入自定义指令
    
    // 注册指令
    Vue.directive('draggable', vDraggable);
    
    new Vue({
      render: h => h(App),
    }).$mount('#app');
    
  • 局部注册

    <template>
      <div>
        <!-- 使用局部注册的指令 v-draggable -->
        <div v-draggable class="draggable-box">
          <p>拖拽我!</p>
        </div>
      </div>
    </template>
    
    <script>
    // 导入你写的拖拽指令
    import vDraggable from './directives/v-draggable';
    
    export default {
      name: 'DraggableComponent',
      directives: {
        draggable: vDraggable // 局部注册指令
      }
    };
    </script>
    
    <style scoped>
    .draggable-box {
      position: absolute;
      width: 200px;
      height: 150px;
      background-color: #f0f0f0;
      border: 1px solid #ccc;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
      padding: 10px;
      cursor: move;
    }
    </style>