问题:使用vueuse
的useDraggable
去拽按钮时会触发点击事件,即使设置阻止默认事件还是没用。
方案1:判断拖拽时长
判断拖拽时长,如果大于点击的时间秒数,则被认为是拖拽。小于被认为是点击,则触发点击事件。
按钮点击时,也会触发onStart
和onEnd
回调函数。
缺点:如果点击时按下鼠标很长时间后才松开,会被误认为拖拽(虽然没人点击按钮这么按,万一…), 所以第二种方式会更好些!!
<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>