当前位置:首页 > VUE

vue实现弹框拖动

2026-02-24 16:43:31VUE

Vue 实现弹框拖动功能

核心思路

通过监听鼠标事件(mousedown、mousemove、mouseup)计算弹框的偏移量,结合 CSS 的 transformposition 属性实现拖动效果。

基础实现代码

<template>
  <div 
    class="draggable-dialog" 
    ref="dialog"
    :style="{ left: position.x + 'px', top: position.y + 'px' }"
    @mousedown="startDrag"
  >
    <!-- 弹框内容 -->
    <div class="dialog-content">
      <slot></slot>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      position: { x: 0, y: 0 },
      isDragging: false,
      startPos: { x: 0, y: 0 }
    };
  },
  methods: {
    startDrag(e) {
      this.isDragging = true;
      this.startPos = {
        x: e.clientX - this.position.x,
        y: e.clientY - this.position.y
      };
      document.addEventListener('mousemove', this.onDrag);
      document.addEventListener('mouseup', this.stopDrag);
    },
    onDrag(e) {
      if (!this.isDragging) return;
      this.position = {
        x: e.clientX - this.startPos.x,
        y: e.clientY - this.startPos.y
      };
    },
    stopDrag() {
      this.isDragging = false;
      document.removeEventListener('mousemove', this.onDrag);
      document.removeEventListener('mouseup', this.stopDrag);
    }
  }
};
</script>

<style>
.draggable-dialog {
  position: absolute;
  cursor: move;
  user-select: none;
}
</style>

优化方案

限制拖动范围onDrag 方法中添加边界检测:

onDrag(e) {
  if (!this.isDragging) return;
  const maxX = window.innerWidth - this.$refs.dialog.offsetWidth;
  const maxY = window.innerHeight - this.$refs.dialog.offsetHeight;

  this.position = {
    x: Math.min(maxX, Math.max(0, e.clientX - this.startPos.x)),
    y: Math.min(maxY, Math.max(0, e.clientY - this.startPos.y))
  };
}

使用 transform 优化性能 修改样式和计算方式:

.draggable-dialog {
  position: fixed;
  transform: translate(0, 0);
}
position: {
  x: 0,
  y: 0
},
// 在 onDrag 中:
this.position = {
  x: e.clientX - this.startPos.x,
  y: e.clientY - this.startPos.y
};

组件化方案

创建可复用的 Draggable 高阶组件:

// Draggable.js
export default {
  props: ['x', 'y'],
  data() {
    return {
      position: { x: this.x || 0, y: this.y || 0 },
      // ...其他拖动逻辑
    };
  },
  // ...其他方法
};

使用时:

vue实现弹框拖动

<Draggable :x="100" :y="100">
  <YourDialogComponent />
</Draggable>

注意事项

  1. 移动端需要额外处理 touchstart/touchmove 事件
  2. 复杂场景建议使用第三方库如:
    • vuedraggable
    • interact.js
  3. 拖动时禁用文本选择:
    .draggable-dialog {
      user-select: none;
    }

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

相关文章

vue的艾特功能实现

vue的艾特功能实现

Vue 的 @ 功能实现 在 Vue 中实现类似社交平台的 @ 功能,通常涉及输入框的监听、用户匹配和选择插入。以下是具体实现方法: 监听输入框内容 使用 v-model 绑定输入框内容,并通过 @…

django vue实现

django vue实现

Django与Vue.js整合实现方案 Django作为后端框架与Vue.js作为前端框架的整合,可以通过以下方式实现: 分离式开发 前后端完全分离,Django仅提供API接口,Vue.js通过a…

vue实现tag

vue实现tag

Vue 实现标签(Tag)功能 在 Vue 中实现标签(Tag)功能可以通过多种方式完成,以下是一些常见的方法和实现步骤: 使用动态组件和 v-for 通过 v-for 指令动态渲染标签列表,结合样…

vue实现图册

vue实现图册

Vue实现图册功能 在Vue中实现图册功能通常涉及图片展示、切换、缩放等交互效果。以下是常见的实现方法和关键代码示例: 基础图册组件结构 使用Vue单文件组件构建基础结构: <templat…

vue实现节流

vue实现节流

vue实现节流的方法 在Vue中实现节流(throttle)功能,通常用于限制高频事件的触发频率,例如滚动、输入或按钮点击。以下是几种常见的实现方式: 使用Lodash的throttle函数 安装L…

vue实现订单

vue实现订单

Vue 实现订单功能 订单数据结构设计 订单数据通常包含以下字段: order: { id: String, // 订单ID userId: String,…