vue3编写一个hooks,用于实现鼠标拖拽,并且支持动态设置边界。

148 阅读1分钟

直接上代码吧,感觉也没啥可讲的,因为要用到这个,网上搜了下,也没有找到合适的,所以就自己写了个,顺便分享出来。

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>

如果有什么使用疑问,请回复我哦!