likes
comments
collection
share

vue3功能最强的拖拽库-dnd起步教程

作者站长头像
站长
· 阅读数 47

前沿介绍

之前vue移动拖拽库使用的是vue-draggable,但扩展性偏弱。而dnd在这方面有优势,需要做这个功能的小伙伴,个人建议优先选择dnd。不过dnd有学习成本。此文章就是希望能降低vue3 dnd的学习成本。

上手思路

因为学习思路有问题,个人上手dnd花费了不少时间,望大家不要重蹈覆辙。官方文档的入门教程是有点整蛊的,说是教程,实则只是一堆api的解释。嚼起来费劲,又没啥用。

个人推荐上手思路:

直接跟着我下面的dnd示例做,跑一遍dnd的流程。dnd的代码量其实很少的,做一遍你就知道dnd是怎么运行的,其实就已经是上手了。

然后根据自己需要的业务,去找dnd的官方示例,官方示例有5大模块,每个模块也就三五示例。里面基本涵盖了dnd能实现的常见功能。找到类似自己的业务的示例后,下载官方源码,自己根据官方文档的api,改造示例代码即可。

我先自吹一波,这一套上手思路,上手速度快,业务实现速度也是杠杠的。大家如果觉得有用,给我文章点个赞哈。话不多说,扬帆起航。

🐯 创建一个dnd流程

实现目标:将一个拖拽源拖拽到容器中

vue3功能最强的拖拽库-dnd起步教程

创建一个可以被拖拽的拖拽源(Drag)

<template>
  <div :ref="drag"></div>
</template>
<script lang="ts" setup>
import { useDrag } from "vue3-dnd"
// useDrag即生成一个拖拽源,返回一个构建元素的方法(drag),将drag绑到:ref上,就相当于构建在这个元素上了
const [, drag] = useDrag({ 
  type: "acceptType", //拖拽源的类型,用来给接收容器判断是否接受此拖拽源
  item: () => { // item是拖拽源的数据,接受容器可以接受到这里面的数据
    return { id: props.id }  
  },
})

监听拖拽源的状态

<template>
  <div :ref="drag"></div>
</template>
<script lang="ts" setup>
import { useDrag } from "vue3-dnd"
// 3.collect是拖拽源状态的收集器,拖拽源的状态变化都会反馈到collect上
const [collect, drag] = useDrag({ 
  type: "acceptType",
  item: () => { 
    return { id: props.id }  
  },
  
 // 1.monitor:即拖拽源的监控器,拓展源状态变化了,就会更新monitor
  collect(monitor){ 
    return {}//2.collect:收集器,return出去的对象会赋值到《const [collect, drag] 》里面的collect
  }
})

完整的示例

监听拖拽源是否正在被拖拽中

<template>
  <div :ref="drag"></div>
</template>
<script lang="ts" setup>
import { useDrag } from "vue3-dnd"
// 2.collect是vue的ref方法的返回值,使用时请用collect.value,collect更新会触发update生命周期,会更新依赖
const [collect, drag] = useDrag({
  type: "acceptType",
  item: () => {
    return { id: props.id }
  },
  collect(monitor) {
    return {
      //1.将监控器抛出的状态赋值到isDragging
      isDragging: monitor.isDragging(),
    }
  },
})
// 3.监听collect的变化,做相应的逻辑处理
watch(
  () => collect.value.isDragging,
  (value) => {
    if (value) {
      console.log("正在被拖拽中")
    } else {
      console.log("没有在拖拽了")
    }
  },
)

拖拽源的各种状态变化都在monitor,可查询官方文档api获取自己想监听的状态 vue3功能最强的拖拽库-dnd起步教程

创建一个接受拖拽源的容器(Drop)

<template>
  <div :ref="Drop"></div>
</template>
<script lang="ts" setup>
import { useDrop } from "vue3-dnd"
const [collect, Drop] = useDrop({
  accept: "acceptType", // 容器允许接收的拖拽源类型,即容器只接收此类型的拖拽源
  collect(monitor) {
    return {
      isOver: monitor.isOver(), // 判断拖拽源是否在容器内
      item: monitor.getItem(), //拖拽源传递的数据
    }
  },
})
//监听collect的变化,做相应的逻辑处理
watch(
  () => collect.value,
  (value) => {
    if (value.isOver) {
      console.log("拖拽源移动到容器范围内了")
      console.log("这是拖拽源的数据", value.item)
    } else {
      console.log("拖拽源移动到容器范围外面了")
    }
  },
  { deep: true },
)

实时监听容器内的情况

####示例 实时监听容器内的拖拽源位置变化

<template>
  <div :ref="Drop"></div>
</template>
<script lang="ts" setup>
import { useDrop } from "vue3-dnd"
const [collect, Drop] = useDrop({
  accept: "acceptType", 
  hover(item,monitor) { //实时监听正在容器内移动的数据源,每个0.1秒左右就触发一次
    console.log('拖拽源的数据',item)
    console.log('拖拽源的位置',monitor.getClientOffset())
  },
})

备注:拖拽源也有自己的实时监听方法,具体方法api请见文档。

  • 常用的实时监听事件
名称说明
drop()拖拽源放置结束后触发事件

至此,你已经实现了一个完整的拖拽功能了,想必也理解dnd的运作过程了。如果还不理解,那就回头看看自己的代码,多玩一下自己实现的示例。

如何使用dnd实现自己的业务

实现自己需要的业务时,可先查看官方文档的示例,里面基本涵盖了dnd能实现的常见功能。找到类似自己的业务的示例后,下载官方源码,自己根据官方文档的api,改造示例代码即可。

转载自:https://juejin.cn/post/7338605981595566143
评论
请登录