拖拽按钮: 如何区分点击和拖拽事件 (vueuse实现)

问题:使用vueuseuseDraggable去拽按钮时会触发点击事件,即使设置阻止默认事件还是没用。
在这里插入图片描述

方案1:判断拖拽时长

判断拖拽时长,如果大于点击的时间秒数,则被认为是拖拽。小于被认为是点击,则触发点击事件。
按钮点击时,也会触发onStartonEnd回调函数。
缺点:如果点击时按下鼠标很长时间后才松开,会被误认为拖拽(虽然没人点击按钮这么按,万一…), 所以第二种方式会更好些!!

<template>
  <!--左侧可折叠/展开菜单  -->
  <Transition>
    <div v-show="menuVisible" class="flex flex-column bg-white">
      <div class="menu-header" @click="() => menuVisible = false">
        <span class="header-title">{{  props.menuTitle}}</span>
        <el-tooltip effect="dark" :content="props.menuIconTip" :placement="props.menuIconTipPosition" :hide-after="50">
          <el-icon size="22" color="#333333bd"><DArrowLeft /></el-icon>
        </el-tooltip>
      </div>
      <slot name="menu"></slot>
    </div>
  </Transition>
  <!-- 可拖拽悬浮按钮 -->
  <div ref="el" class="btn-wrap" :style="style" style="position: fixed">
      <el-tooltip  effect="dark" :content="props.btnTip" :placement="props.btnTipPosition" :hide-after="100">
       <Transition>
        <div class="btn-block" v-show="!menuVisible">
          <slot name="btn">
            <img src="@/assets/images/menu.svg" class="w-25 h-25" />
          </slot>
        </div>
       </Transition>
      </el-tooltip>
    </div>
</template>
<script setup lang="ts">
import { useDraggable, useWindowSize,Position } from '@vueuse/core';

// 与这部分相关的逻辑代码
const el = ref<HTMLElement | null>(null);
const { width, height } = useWindowSize();
const startTime = ref(null);
const draggedTime = ref(0);

const { x, y, style } = useDraggable(el, {
  initialValue: { x: 125, y: height.value - 100 },
  preventDefault: true,// 默认为false时,拖拽按钮后松开鼠标后,按钮仍黏在光标上
  onMove: (position: Position) => {
    // 右边缘限制
    if (position.x > width.value - 60) {
      position.x = width.value - 60;
    }
    // 左边缘限制
    if (position.x < 99) {
      position.x = 99;
    }
    // 上边缘限制
    if (position.y < 160) {
      position.y = 160;
    }
    // 下边缘限制
    if (position.y > height.value - 75) {
      position.y = height.value - 75;
    }
  },
  onStart: () => {
    startTime.value = new Date();
  },
  onEnd: () => {
    const endTime = new Date();
    // 计算拖拽开始和结束的时间差秒数                                                                                                                                                                                                            
    const timeDiff = (endTime.getTime() - startTime.value.getTime()) / 1000;
    draggedTime.value = Number(timeDiff.toFixed(2));
    console.log(draggedTime.value, 'draggedTime');
    if (draggedTime.value < 0.15) {
      //点击后的事件
      menuVisible.value = true;
    }
  },
});
</script>

方案 2:onMove中判断

按钮只有在拖拽时才会触发onMove回调函数,触发改函数则表示在拖拽中。

<template>
<!-- 可拖拽悬浮按钮 -->
  <div ref="el" class="btn-wrap" :style="style" style="position: fixed">
    <el-tooltip
      :visible="btnTipVisible"
      effect="dark"
      :content="props.btnTip"
      :placement="props.btnTipPosition"
      :hide-after="100">
      <!-- 绑定点击事件 -->
      <div class="btn-block" v-show="!menuVisible" @click="handleBtnClick">
        <img src="@/assets/images/tree.svg" class="w-25 h-25" />
      </div>
    </el-tooltip>
  </div>
</template>
<script setup lang="ts">
  import { useDraggable, useWindowSize,Position } from '@vueuse/core';

// 与这部分相关的逻辑代码
const el = ref<HTMLElement | null>(null);
const { width, height } = useWindowSize();
  
const isDragging = ref(false);// 判断是否在拖拽
  
const { x, y, style } = useDraggable(el, {
  initialValue: { x: 125, y: height.value - 100 },
  preventDefault: true,
  onMove: (position: Position) => {
    isDragging.value = true;
    // 右边缘限制
    if (position.x > width.value - 60) {
      position.x = width.value - 60;
    }
    // 左边缘限制
    if (position.x < 99) {
      position.x = 99;
    }
    // 上边缘限制
    if (position.y < 160) {
      position.y = 160;
    }
    // 下边缘限制
    if (position.y > height.value - 75) {
      position.y = height.value - 75;
    }
  },
});
const handleBtnClick = (e) => {
  if (isDragging.value) {
    e.preventDefault();
    isDragging.value = false;
  } else {
    menuVisible.value = !menuVisible.value;
  }
};
</script>
  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对不起,我之前给出的示例是基于 Vue 2.x 的。对于 Vue 3.x,你可以使用 `vue-draggable-next` 插件来实现按钮在区域内任意拖拽移动的功能。 首先,确保你已经安装了 `vue-draggable-next` 插件。 接下来,在你的 Vue 组件中,你可以使用 `v-draggable` 指令来使按钮拖拽。在按钮元素上添加 `v-draggable` 指令,并指定一个唯一的标识符,以便在拖拽事件中识别该按钮。 例如: ```html <template> <div> <div class="drag-area"> <button v-draggable="buttonId" @drag="handleDrag">Drag me</button> </div> </div> </template> <script> import { ref } from 'vue'; import { draggable } from 'vue-draggable-next'; export default { setup() { const buttonId = ref('myButton'); const handleDrag = (event) => { // 处理拖拽事件 console.log('Button dragged', event); }; return { buttonId, handleDrag }; }, components: { draggable } }; </script> <style scoped> .drag-area { width: 300px; height: 300px; border: 1px solid #ccc; } </style> ``` 在上面的示例中,我们使用了 Vue 3.x 的 Composition API,通过 `setup` 函数来设置我们的组件。 在 `setup` 函数中,我们使用 `ref` 来创建一个响应式的 `buttonId` 变量,并在 `handleDrag` 方法中处理拖拽事件。 在组件的选项中,我们将 `draggable` 组件注册为局部组件。 这样,你就可以使用 `vue-draggable-next` 插件来实现按钮在区域内任意拖拽移动的功能了。记得在组件中引入和注册 `vue-draggable-next` 插件。 ```javascript import { createApp } from 'vue'; import { createRouter, createWebHistory } from 'vue-router'; import draggable from 'vue-draggable-next'; const app = createApp(App); const router = createRouter({ history: createWebHistory(), routes }); app.use(router); app.component('draggable', draggable); app.mount('#app'); ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值