直接上代码吧,感觉也没啥可讲的,因为要用到这个,网上搜了下,也没有找到合适的,所以就自己写了个,顺便分享出来。
import { ref, onMounted, onUnmounted } from 'vue'
export default function useDraggable (limits = {}) {
const isDown = ref(false)
const offsetX = ref(0)
const offsetY = ref(0)
const elementRef = ref(null)
const onMouseMove = (e) => {
if (isDown.value && elementRef.value) {
let newLeft = e.clientX - offsetX.value
let newTop = e.clientY - offsetY.value
const windowWidth = window.innerWidth
const windowHeight = window.innerHeight
if (limits.left !== undefined && newLeft < limits.left) {
newLeft = limits.left
}
if (limits.right !== undefined && newLeft + elementRef.value.offsetWidth > windowWidth - limits.right) {
newLeft = windowWidth - limits.right - elementRef.value.offsetWidth
}
if (limits.top !== undefined && newTop < limits.top) {
newTop = limits.top
}
if (limits.bottom !== undefined && newTop + elementRef.value.offsetHeight > windowHeight - limits.bottom) {
newTop = windowHeight - limits.bottom - elementRef.value.offsetHeight
}
elementRef.value.style.left = newLeft + 'px'
elementRef.value.style.top = newTop + 'px'
elementRef.value.style.bottom = 'auto'
elementRef.value.style.right = 'auto'
}
}
const onMouseDown = (e) => {
if (elementRef.value) {
e.preventDefault()
isDown.value = true
offsetX.value = e.clientX - elementRef.value.getBoundingClientRect().left
offsetY.value = e.clientY - elementRef.value.getBoundingClientRect().top
elementRef.value.style.position = 'absolute'
}
}
const onMouseUp = () => {
isDown.value = false
}
onMounted(() => {
document.addEventListener('mousemove', onMouseMove)
document.addEventListener('mouseup', onMouseUp)
})
onUnmounted(() => {
document.removeEventListener('mousemove', onMouseMove)
document.removeEventListener('mouseup', onMouseUp)
})
return {
elementRef,
onMouseDown
}
}
如何使用呢?
<template>
<div ref="elementRef" @mousedown="onMouseDown" />
</template>
<script setup>
import useDraggable from '@/hooks/useDraggable';
// 这里传入的参数为边界限制,拖拽时判断上下左右的临界距离
const { elementRef, onMouseDown } = useDraggable({
left: 0,
right: 0,
top: document.querySelector('.routes').clientHeight,
bottom: 0
});
</script>
如果你在组件中还要使用这个元素的ref引用,那么你应该像下面这样做:
<template>
<div ref="cusRef" @mousedown="onMouseDown" />
</template>
<script setup>
import useDraggable from '@/hooks/useDraggable';
// 这里传入的参数为边界限制,拖拽时判断上下左右的临界距离
const { elementRef, onMouseDown } = useDraggable({
left: 0,
right: 0,
top: document.querySelector('.routes').clientHeight,
bottom: 0
});
const cusRef = ref(null)
onMounted(() => {
elementRef.value = cusRef.value
})
</script>
如果有什么使用疑问,请回复我哦!