首页 > 其他分享 >vue 通过 directives 实现弹窗div可以拖动

vue 通过 directives 实现弹窗div可以拖动

时间:2024-12-27 14:21:44浏览次数:7  
标签:el vue 鼠标 拖动 元素 draggable directives div 弹窗

在 Vue 2 中,可以通过自定义指令(v-draggable)来实现弹窗 div 拖动的功能。自定义指令允许我们将拖动功能封装起来,使得在多个地方复用。下面是一个实现拖动功能的完整示例:

实现步骤:

  1. 创建一个自定义指令 v-draggable 来处理拖动逻辑。
  2. 将该指令应用于你想要拖动的元素(例如弹窗 div)。

示例代码:

<template>
  <div class="app">
    <div
      v-draggable
      class="draggable-window"
      :style="{ left: position.x + 'px', top: position.y + 'px' }"
    >
      <div class="window-header">
        <span>拖动弹窗</span>
      </div>
      <div class="window-content">
        <p>这里是弹窗内容</p>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      position: { x: 100, y: 100 }, // 初始位置
    };
  },
};
</script>

<script>
// 自定义指令 v-draggable
Vue.directive('draggable', {
  bind(el) {
    let isDragging = false;   // 是否正在拖动
    let offsetX = 0;          // 鼠标与元素的水平偏移
    let offsetY = 0;          // 鼠标与元素的垂直偏移

    // 鼠标按下事件
    const onm ouseDown = (event) => {
      isDragging = true;
      offsetX = event.clientX - el.offsetLeft;
      offsetY = event.clientY - el.offsetTop;
      
      // 阻止选中文本
      document.body.style.userSelect = 'none';

      // 绑定鼠标移动和鼠标释放事件
      document.addEventListener('mousemove', onm ouseMove);
      document.addEventListener('mouseup', onm ouseUp);
    };

    // 鼠标移动事件
    const onm ouseMove = (event) => {
      if (isDragging) {
        // 更新元素的位置
        el.style.left = `${event.clientX - offsetX}px`;
        el.style.top = `${event.clientY - offsetY}px`;
      }
    };

    // 鼠标释放事件
    const onm ouseUp = () => {
      isDragging = false;
      
      // 恢复文本选择
      document.body.style.userSelect = '';

      // 移除事件监听
      document.removeEventListener('mousemove', onm ouseMove);
      document.removeEventListener('mouseup', onm ouseUp);
    };

    // 绑定鼠标按下事件到目标元素
    el.querySelector('.window-header').addEventListener('mousedown', onm ouseDown);
  }
});
</script>

<style scoped>
.app {
  position: relative;
}

.draggable-window {
  position: absolute;
  width: 300px;
  height: 200px;
  border: 1px solid #ccc;
  background-color: white;
  box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
  cursor: move;
}

.window-header {
  background-color: #f1f1f1;
  padding: 10px;
  cursor: move;
  font-weight: bold;
}

.window-content {
  padding: 20px;
}
</style>

解释

1. 自定义指令 v-draggable

  • bind 钩子:这个钩子在指令绑定到元素时被调用。我们在这个钩子里添加了拖动的逻辑。

  • onMouseDown:当用户按下鼠标时,记录鼠标和元素的偏移量,并开始监听 mousemovemouseup 事件。

  • onMouseMove:在鼠标移动时,如果处于拖动状态,更新元素的位置。

  • onMouseUp:当用户释放鼠标时,停止拖动并移除事件监听。

2. 样式:

  • .draggable-window 使用 position: absolute,使得元素可以随意定位,并且添加了 cursor: move 来指示该元素是可拖动的。

  • .window-header 设置了拖动区域,用户可以点击这个区域来拖动整个窗口。

3. 如何使用:

在 HTML 代码中,将 v-draggable 指令应用于需要拖动的元素。该指令会自动为指定的元素添加拖动行为。

4. 注意事项:

  • v-draggable 指令默认只能在 .window-header 部分触发拖动。你可以根据需要修改为任何元素来控制拖动区域。

  • 如果你希望限制窗口的拖动范围,可以在 onMouseMove 中添加限制逻辑,确保窗口不会超出某个区域。

优化和扩展:

  • 限制窗口范围:通过限制 el.style.leftel.style.top 的最大值和最小值,来防止弹窗被拖出视窗。

  • 响应式设计:如果希望窗口在不同屏幕尺寸下也能够适应,可以动态设置 lefttop

总结:

使用自定义指令 v-draggable 可以简洁地为 Vue 2 中的弹窗或任何元素实现拖动功能。这样,我们的拖动逻辑可以在不同的组件中复用,并且避免了冗余的代码。

======

这种方式实际是可行的,项目中看到这种用法,但上面的答案来自chatgpt,没验证过

标签:el,vue,鼠标,拖动,元素,draggable,directives,div,弹窗
From: https://www.cnblogs.com/pansidong/p/18635645

相关文章

  • 学生考勤系统|Java|SSM|VUE| 前后端分离
                 【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetomcat......
  • 勤工助学系统|Java|SSM|VUE| 前后端分离
                 【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetomcat......
  • 企业销售人员培训系统|Java|SSM|VUE| 前后端分离
                 【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetomcat......
  • 农家乐系统|Java|SSM|VUE| 前后端分离
                 【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetomca......
  • vue3 表格下拉刷新
    <scriptsetuplang="ts">import{Empty}from'ant-design-vue';exportinterfaceTBColumn{title:stringdataIndex:string//key:stringellipsis?:booleanwidth?:stringalign?:string[key:string]:any}con......
  • vue3 拖动弹窗
    <scriptsetuplang="ts">import{useDraggable,useMouseInElement}from'@vueuse/core';importtype{CSSProperties}from'vue';interfaceProps{isMask?:booleandialogStyle?:Record<string,any>......
  • 46.在 Vue3 中使用 OpenLayers 双击鼠标显示品牌代言人名片
    在现代Web开发中,地图可视化已成为非常常见的需求之一,尤其是在地理位置相关的应用中。OpenLayers是一款强大的开源JavaScript库,能够帮助开发者在网页中实现各种地图功能。结合Vue3的强大功能,我们可以轻松地将OpenLayers集成到Vue项目中,展示地图上的地理信息。本文......
  • Vue 核心知识:内置组件Keeplive
    让我们一起走向未来......
  • Java基于SpringBoot的高校社团管理系统的设计与实现-java vue.js idea
    所需该项目可以在最下面查看联系方式,为防止迷路可以收藏文章,以防后期找不到项目介绍Java基于SpringBoot的高校社团管理系统的设计与实现-javavue.jsidea系统实现截图技术栈介绍JDK版本:jdk1.8+编程语言:java框架支持:springboot数据库:mysql版本不限......
  • Java基于SpringBoot的装修公司管理平台-java vue.js idea
    所需该项目可以在最下面查看联系方式,为防止迷路可以收藏文章,以防后期找不到项目介绍Java基于SpringBoot的装修公司管理平台-javavue.jsidea系统实现截图技术栈介绍JDK版本:jdk1.8+编程语言:java框架支持:springboot数据库:mysql版本不限数据库工具:Navicat/......