vue3功能最强的拖拽库-dnd起步教程
前沿介绍
之前vue移动拖拽库使用的是vue-draggable,但扩展性偏弱。而dnd在这方面有优势,需要做这个功能的小伙伴,个人建议优先选择dnd。不过dnd有学习成本。此文章就是希望能降低vue3 dnd的学习成本。
上手思路
因为学习思路有问题,个人上手dnd花费了不少时间,望大家不要重蹈覆辙。官方文档的入门教程是有点整蛊的,说是教程,实则只是一堆api的解释。嚼起来费劲,又没啥用。
个人推荐上手思路:
直接跟着我下面的dnd示例做,跑一遍dnd的流程。dnd的代码量其实很少的,做一遍你就知道dnd是怎么运行的,其实就已经是上手了。
然后根据自己需要的业务,去找dnd的官方示例,官方示例有5大模块,每个模块也就三五示例。里面基本涵盖了dnd能实现的常见功能。找到类似自己的业务的示例后,下载官方源码,自己根据官方文档的api,改造示例代码即可。
我先自吹一波,这一套上手思路,上手速度快,业务实现速度也是杠杠的。大家如果觉得有用,给我文章点个赞哈。话不多说,扬帆起航。
🐯 创建一个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获取自己想监听的状态
创建一个接受拖拽源的容器(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