Vue实现高自由度的自定义拖拽指令

目录

前言

 源码

使用方式

1、拖动元素本身

2、拖动指定区域

总结


前言

在我的一个项目中有很多自定义的弹框,它们都需要可以随意拖拽,因此我封装了一个vue的自定义指令去实现,只要在需要拖动的元素上加上此指令即可变成可拖动元素。该组件除了可以让元素随意拖动,还能指定鼠标拖动元素上哪个区域才能拖动。

 源码

在main.ts或main.js里注册:

const app = createApp(App);

app.directive('drag', (el, binding) => {
  // 定义一个变量target来存储元素或者绑定的值
  let target: any = null;

  // 如果绑定了一个值,则将target设置为这个值,否则设置为el本身(即被拖拽的元素)
  target = binding.value ? binding.value : el;

  // 要实现拖动改变位置还需设置元素为绝对定位
  target.style.position='absolute'

  // 为元素添加鼠标按下事件监听,用于开始拖拽
  el.onmousedown = (e) => {
    // 阻止选择文本,防止在拖拽过程中选中文字
    document.onselectstart = () => {
      return false;
    };

    // 计算鼠标与目标元素之间的水平方向和垂直方向的距离
    const disX = e.clientX - target.offsetLeft;
    const disY = e.clientY - target.offsetTop;

    // 为document添加鼠标移动事件监听
    document.onmousemove = (e) => {
      // 计算移动后的位置,并设置元素的新位置
      const l = e.clientX - disX;
      const t = e.clientY - disY;
      if (l > 10 && t > 10) { // 判断移动的距离是否超过10像素,避免过于微小的移动
        target.style.left = l + 'px';
        target.style.top = t + 'px';
      }
    };

    // 为document添加鼠标释放事件监听,用于结束拖拽
    document.onmouseup = (e) => {
      // 停止监听鼠标移动和释放事件,以及恢复onselectstart的行为
      document.onmousemove = null;
      document.onmouseup = null;
      document.onselectstart = null;
    };

    // 阻止默认的鼠标按下事件行为
    // return false不加的话可能导致黏连,即拖拽结束后鼠标依然被绑定在元素上
    return false;
  };
});

使用方式

1、拖动元素本身

在需要拖拽的元素上添加v-drag指令,即可实现对该元素的拖拽。在这种情况下,用户可以按住元素的任何区域进行拖拽。

<template>
  <div class="drag_div" v-drag> </div>
</template>

<style>
  .drag_div {
    background-color: red;
    height: 200px;
    width: 200px;
  }
</style>

按住红色方块任何区域都可以拖动,拖动的是整个红色方块

2、拖动指定区域

在元素上使用v-drag="xxx",其中xxx为需要拖拽元素的ref值。在这种情况下,用户只能按住添加了v-drag="xxx"的元素进行拖拽,实际被拖拽的是对应的ref元素。

<template>
  <div class="drag_div" ref="dragRef">
    <div class="inner_div" v-drag="dragRef"></div>
  </div>
</template>

<script setup lang="ts">
  import { ref } from 'vue';
  const dragRef = ref();
</script>
<style>
  .drag_div {
    background-color: red;
    height: 200px;
    width: 200px;
  }
  .inner_div {
    height: 50px;
    width: 50px;
    background-color: #f1b0b9;
  }
</style>

只有按住红色方块里的粉色小方块时才能拖动,拖动的是整个红色方块 。

总结

该拖拽功能的实现原理主要是通过鼠标事件监听,计算鼠标与目标元素之间的距离,然后在鼠标移动时更新元素的位置。在鼠标释放时,清除相关的事件监听,结束拖拽操作。
这种拖拽功能的实现方式简洁明了,易于理解和使用。可以根据实际需求,灵活运用在网页开发中。

  • 45
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

马可家的菠萝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值