vueUse地址:

https://vueuse.org/core/useDraggable/

useDraggable 让一个元素变成可拖拽

官方给出的demo,感兴趣的可以去VueUse官网看看

<script setup lang="ts">
import { ref } from 'vue'
import { useDraggable } from '@vueuse/core'
 
const el = ref<HTMLElement | null>(null)
 
// `style` will be a helper computed for `left: ?px; top: ?px;`
const { x, y, style } = useDraggable(el, {
  initialValue: { x: 40, y: 40 },
})
</script>
 
<template>
  <div ref="el" :style="style" style="position: fixed">
    Drag me! I am at {{x}}, {{y}}
  </div>
</template>

useDraggable接收两个参数,target拖拽目标元素。options为可选参数,也就是你传不传都可以 。下面的代码为useDraggable的部分源码,可以看到options参数是一个对象,里面有初始值,拖拽方式,监听事件等等。感兴趣的可以去看看源码。

interface UseDraggableOptions {
    /**
     * Only start the dragging when click on the element directly
     *
     * @default false
     */
    exact?: MaybeRef<boolean>;
    /**
     * Prevent events defaults
     *
     * @default false
     */
    preventDefault?: MaybeRef<boolean>;
    /**
     * Prevent events propagation
     *
     * @default false
     */
    stopPropagation?: MaybeRef<boolean>;
    /**
     * Element to attach `pointermove` and `pointerup` events to.
     *
     * @default window
     */
    draggingElement?: MaybeRef<HTMLElement | SVGElement | Window | Document | null | undefined>;
    /**
     * Pointer types that listen to.
     *
     * @default ['mouse', 'touch', 'pen']
     */
    pointerTypes?: PointerType[];
    /**
     * Initial position of the element.
     *
     * @default { x: 0, y: 0}
     */
    initialValue?: MaybeRef<Position>;
    /**
     * Callback when the dragging starts. Return `false` to prevent dragging.
     */
    onStart?: (position: Position, event: PointerEvent) => void | false;
    /**
     * Callback during dragging.
     */
    onMove?: (position: Position, event: PointerEvent) => void;
    /**
     * Callback when dragging end.
     */
    onEnd?: (position: Position, event: PointerEvent) => void;
}
 
declare function useDraggable(target: MaybeRef<HTMLElement | SVGElement | null | undefined>, options?: UseDraggableOptions): {
    position: Ref<Position>;
    isDragging: vue_demi.ComputedRef<boolean>;
    style: vue_demi.ComputedRef<string>;
    x: Ref<number>;
    y: Ref<number>;
};

看到这个工具的时候,我的第一想法是让我的全局设置变成一个可自由摆放,自由拖拽的小组件。这样让我平平无奇的页面增加了一丝丝桌面应用的感觉。显得高大上一点。同样,你还可以去实现弹出框,对话框的自由拖拽等等。自由发挥想象,反正有了这个工具你少写很多代码,而且减少bug风险,毕竟是vue官方工具。好了,废话不多说,下面上例子。

<template>
  <div ref="settingRef" :style="style" style="position: fixed">
    <el-icon size="40px"><i-ep-setting /></el-icon>
  </div>
</template>
 
<script lang="ts">
import {useWindowSize, useDraggable, Position} from "@vueuse/core";
export default defineComponent({
  setup() {
    const settingRef = ref<HTMLElement | null>(null)
 
    const { width, height } = useWindowSize()
 
    let { style } = useDraggable(settingRef, {
      initialValue: { x: width.value - 40, y: height.value / 2 },
      onMove: (position: Position) => {
        if (position.x > width.value - 40) {
          position.x = width.value - 40
        }
        if (position.x < 0) {
          position.x = 0
        }
        if (position.y > height.value - 40) {
          position.y = height.value - 40
        }
        if (position.y < 0) {
          position.y = 0
        }
      }
    })
 
    return {
      settingRef,
      style,
    }
  }
})
</script>

 

 

 

感兴趣的小伙伴可以运行这个demo试试,代码中使用useWindowSize获取窗口大小,监听了onMove方法。拖拽的元素只能在窗口范围内拖拽。其中-40的部分是减掉元素本身的大小。这里只是一个简单的demo,没有去处理窗口大小变化的时候,所以感兴趣的小伙伴可以自行往下扩展

Logo

前往低代码交流专区

更多推荐