当前位置:首页 > VUE

vue实现拖动div

2026-02-19 18:07:11VUE

实现拖动 Div 的基本思路

通过 Vue 的指令或组件封装,结合原生 DOM 事件(mousedownmousemovemouseup)实现拖动功能。核心逻辑是计算鼠标移动的偏移量,动态更新目标元素的定位样式(如 lefttop)。

方法一:使用自定义指令

  1. 创建自定义指令
    在 Vue 中注册一个全局或局部指令,监听目标元素的鼠标事件:

    Vue.directive('drag', {
      bind(el) {
        let isDragging = false;
        let offsetX, offsetY;
    
        el.addEventListener('mousedown', (e) => {
          isDragging = true;
          offsetX = e.clientX - el.getBoundingClientRect().left;
          offsetY = e.clientY - el.getBoundingClientRect().top;
          el.style.position = 'absolute'; // 确保元素可定位
        });
    
        document.addEventListener('mousemove', (e) => {
          if (!isDragging) return;
          el.style.left = `${e.clientX - offsetX}px`;
          el.style.top = `${e.clientY - offsetY}px`;
        });
    
        document.addEventListener('mouseup', () => {
          isDragging = false;
        });
      }
    });
  2. 在模板中使用指令
    通过 v-drag 指令绑定到目标元素:

    <template>
      <div v-drag class="draggable-div">拖拽我</div>
    </template>

方法二:封装为可复用组件

  1. 创建拖动组件
    将逻辑封装为组件,通过 props 控制拖动行为:

    vue实现拖动div

    export default {
      props: {
        initialPosition: { type: Object, default: () => ({ x: 0, y: 0 }) }
      },
      data() {
        return {
          position: { ...this.initialPosition },
          isDragging: false,
          offset: { x: 0, y: 0 }
        };
      },
      methods: {
        startDrag(e) {
          this.isDragging = true;
          this.offset.x = e.clientX - this.position.x;
          this.offset.y = e.clientY - this.position.y;
        },
        onDrag(e) {
          if (!this.isDragging) return;
          this.position.x = e.clientX - this.offset.x;
          this.position.y = e.clientY - this.offset.y;
        },
        stopDrag() {
          this.isDragging = false;
        }
      },
      mounted() {
        document.addEventListener('mousemove', this.onDrag);
        document.addEventListener('mouseup', this.stopDrag);
      },
      beforeDestroy() {
        document.removeEventListener('mousemove', this.onDrag);
        document.removeEventListener('mouseup', this.stopDrag);
      }
    };
  2. 在模板中使用组件
    通过样式绑定动态更新位置:

    <template>
      <div
        class="draggable-component"
        :style="{ left: `${position.x}px`, top: `${position.y}px` }"
        @mousedown="startDrag"
      >
        拖拽我
      </div>
    </template>

方法三:使用第三方库

  1. 安装 vuedraggable
    适用于列表拖拽排序,但也可调整配置实现自由拖动:

    npm install vuedraggable
  2. 配置自由拖动模式
    通过 draggable 选项和 CSS 调整:

    vue实现拖动div

    import draggable from 'vuedraggable';
    export default {
      components: { draggable },
      data() {
        return { list: [{ id: 1, text: '拖拽元素' }] };
      }
    };
    <template>
      <draggable v-model="list" :options="{ group: 'free' }">
        <div v-for="item in list" :key="item.id" class="draggable-item">
          {{ item.text }}
        </div>
      </draggable>
    </template>

注意事项

  • 性能优化
    频繁的 DOM 操作可能影响性能,建议使用 transform 替代 left/top

    .draggable-div {
      transform: translate(0, 0);
    }
  • 边界限制
    添加逻辑限制拖动范围,防止元素超出视口:

    onDrag(e) {
      const maxX = window.innerWidth - el.offsetWidth;
      const maxY = window.innerHeight - el.offsetHeight;
      this.position.x = Math.min(maxX, Math.max(0, e.clientX - this.offset.x));
      this.position.y = Math.min(maxY, Math.max(0, e.clientY - this.offset.y));
    }
  • 移动端支持
    需额外监听 touchstarttouchmovetouchend 事件。

标签: 拖动vue
分享给朋友:

相关文章

vue实现多级表头

vue实现多级表头

Vue 实现多级表头的方法 使用 el-table 组件 Element UI 的 el-table 组件支持多级表头的实现,通过嵌套 el-table-column 即可完成。 <el-ta…

vue实现store

vue实现store

Vue 实现 Store 在 Vue 中,可以通过 Vuex 或 Pinia 实现全局状态管理(Store)。以下是两种主流方案的实现方法。 使用 Vuex 实现 Store Vuex 是 Vue…

vue实现复选

vue实现复选

Vue 实现复选框 在 Vue 中实现复选框可以通过 v-model 指令绑定数据,同时结合 input 元素的 type="checkbox" 属性来实现。以下是几种常见的实现方式: 单个复选框…

vue插件实现

vue插件实现

Vue 插件实现方法 Vue 插件是一种向 Vue 应用程序添加全局功能的机制。插件可以包含全局指令、过滤器、混入、实例方法等。 插件的基本结构 一个 Vue 插件通常是一个对象或函数,需要暴露一个…

vue 实现轮播

vue 实现轮播

Vue 实现轮播的方法 使用第三方库(如 Swiper) 安装 Swiper 库: npm install swiper 在 Vue 组件中引入 Swiper: <template&…

vue 实现树状

vue 实现树状

Vue 实现树状结构的方法 递归组件实现树状结构 递归组件是 Vue 中实现树状结构的常见方法。通过组件自身调用自身,可以轻松构建多层级树状结构。 <template> <ul…