当前位置:首页 > 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 },
      // ...其他拖动逻辑
    };
  },
  // ...其他方法
};

使用时:

<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实现横向导航的方法 使用Flex布局实现横向导航 在Vue中可以通过Flex布局快速实现横向导航。创建一个组件,使用display: flex和flex-direction: row属性使导航项…

vue 实现菜单

vue 实现菜单

Vue 实现菜单的方法 使用 Vue 实现菜单可以通过多种方式,以下是几种常见的方法: 使用 Vue Router 实现动态路由菜单 通过 Vue Router 可以动态生成菜单,根据路由配置自动…

vue实现方法

vue实现方法

Vue 实现方法 Vue 是一种流行的前端框架,用于构建用户界面和单页应用。以下是几种常见的 Vue 实现方法: 创建 Vue 实例 通过 new Vue() 创建一个 Vue 实例,传入配置对象,…

vue实现input

vue实现input

Vue 实现 Input 输入框的方法 基本双向绑定 使用 v-model 指令实现双向数据绑定,适用于大多数表单场景: <template> <input v-model="…

vue实现排序

vue实现排序

Vue 实现排序的方法 在 Vue 中实现排序可以通过多种方式完成,以下是一些常见的方法: 使用计算属性排序数组 计算属性非常适合对数据进行排序,因为它会在依赖的数据变化时自动更新。以下是一个示例:…

vue 实现过滤

vue 实现过滤

Vue 实现过滤的方法 在 Vue 中实现过滤功能可以通过多种方式完成,包括使用计算属性、自定义过滤器、第三方库等。以下是几种常见的实现方法: 使用计算属性进行过滤 计算属性是 Vue 中最常用的过…