vue3使用拖拽组件draggable.next的使用教程【保姆级】

article/2025/8/14 19:11:27

环境:vue3+setup语法

首先放官方文档的链接:

中文版本: https://www.itxst.com/vue-draggable-next/tutorial.html (民间翻译)

英文版本:https://github.com/SortableJS/vue.draggable.next

因为自己写的过程中,官方文档和网上的资料都非常不明,使用版本各不相同,极易踩坑,自己写完后就总结一下,与诸位共勉。

(一)首先,明确需求:

做一个可重复拖拽生成的表格设计器,效果图如下:

(二)搭一个基本的可互相拖拽的框架

(1)在终端使用npm命令下载插件

npm i -S vuedraggable@next//导入
import draggable from 'vuedraggable'

(2)拖拽插件大致可分为两种使用方式——分组拖拽与单组拖拽

单组拖拽为只有一组数据,而拖拽是交换此组数据内部的位置,如下图所示:

而互相拖拽是有两组数据,两组数据可以各自内部换顺序,可以相互拖拽到对方的数组中。

本文需求只用到了互相拖拽,互相拖拽的代码形式如下:

    //需要克隆的数据,A组<draggable :list="dragList" ghost-class="ghost" :force-fallback="true" :group="{ name: 'list', pull: 'clone' }":sort="false" itemKey="id"><template #item="{ element }"><div class="item move"><label class="move">{{ element.name }}</label></div></template></draggable>//拖拽的结果,B组<draggable :list="widgetList" ghost-class="ghost" itemKey="id" :force-fallback="true" group="list" :fallback-class="true":fallback-on-body="true"><template #item="{ element }"><div class="item move"><label class="move">{{ element.name }}</label></div></template></draggable><script lang="ts" setup>
import draggable from 'vuedraggable'interface type {name: string,id: number
}
const dragList: type[] = reactive<type[]>([{ name: "单行文本", id: 1 },{ name: "多行文本", id: 2 },{ name: "计数器", id: 3 },{ name: "单选框组", id: 4 },
])const widgetList = reactive<type[]>([{ name: "多行文本", id: 2 },
])

draggable的一些常用的属性我作了整理,方便根据不同的需求取用,可核对表格填写:

属性
说明
类型
是否必填

group

如果是分组拖拽,可通过设置group的name来实现分类。

pull属性代表拖出,put为拖入,

:group="{ name :'list',pull : true, put: false }"

代表这个分组与其他name为list的分组可实现分组拖拽,此分组允许拖出,不允许拖入,pull为‘clone’则代表clone模式,pull与put可写可不写,默认值都为true

Object / string

(分组拖拽时必填)

list

绑定的数据

Array

sort

是否开启排序功能,默认为true,如果设置为false,它所在组无法排序

Boolean

force-fallback

默认false,忽略HTML5的拖拽行为,因为h5里有个属性也是可以拖动,你要自定义ghostClass chosenClass dragClass样式时,建议forceFallback设置为true

Boolean

(设置ghost-class或drag-class时为必填)

ghost-class

:ghostClass=“ghostClass” 设置拖动元素的占位符类名,可以将拖动时的元素设置为不同的样式。自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true。

String

disabled

是否禁用,默认false

Boolean

drag-class

:drag-class="dragClass"拖动元素的样式,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true

Boolean

item-key

每个元素唯一的标识,建议使用id

itemKey='id',注意,此处无需写成变量形式

String

(不填也能运行,但控制台会报警告)

到现在为止,这已经是个互相拖拽的组件了。

(3)如果发现自己写的组件 不能进行拖拽,或者网页上不显示组件 ,或者出现红色报错信息,则检查以下注意点 :

  1. group中name是否一致,group为变量,需要 :group =‘{name:'' }’的形式

  1. AB组的元素要实现互相拖拽,元素的数据结构必须完全一致,如果不放心,可以使用interface来定义一个类型诸如 interface itemType { name : string , id:number }

  1. AB组绑定的数组是否为响应式,如非响应式,会发生拖拽成功,但不能及时响应的情况,可以用这个方法自检-->先进行拖拽,然后在代码的html部分随便加个东西,然后保存,观察网页上是否显示刚才拖拽的内容,如果出现,那就是数组非响应式的问题。

改正:const arr = reactive<itemType[]>([ { name : 'name ' , id : 1 } ])

  1. 在新版vue3中,item插槽是必写的部分,不能使用v-for循环替代。

<draggable><template #item="{ element }"><div class="item move"><label class="move">{{ element.name }}</label></div></template>
</draggable>
  1. item插槽中只允许有一个子元素,此处有个坑,就是如果有两个子元素,但注释掉了一个,也会报错。哪怕实际上这只有一个子元素。

//正确的  
<template #item="{ element }"><div class="item move"><label class="move">{{ element.name }}</label></div></template>//会报错的情况!
<template #item="{ element }"><!-- <div class="class"></div> --><div class="item move"><label class="move">{{ element.name }}</label></div></template>

到此为止,已经实现拖拽成功。有些人可能会碰到这个问题————如果B组为空,向B组内拖第一个组件的时候,会出现拖拽困难,只能往拖拽区的最顶部拖才能成功 / 根本无法拖拽成功。

原因:因为B组的draggable渲染时为一个高度为auto的div,当前组如果为空,高度也为0,可拖拽区就会变得很小或不存在。

解决方法:为B组的draggable设计高度,具体代码为添加类名,在css中设置

<draggable :list="widgetList" ghost-class="ghost" itemKey="id" :force-fallback="true" group="list" :fallback-class="true":fallback-on-body="true" class="drag-content"><template #item="{ element }"><div class="item move"><label class="move">{{ element.name }}</label></div></template></draggable><style lang="less" scoped>.drag-content {height:500px; //建议是外层嵌套一层div,div固定高,此处再设为100%}
</style>

(三)将拖拽后的内容替换为element组件/其它指定内容

我们发现,拖拽后显示的内容可自由定义,在B组的draggable中设置

此时,我们需要完善dragList的数组结构,来映射拖拽后所形成的不同组件

(在组件少的情况下可以这么做)

interface itemType {name: string,id: number,element:string
}const dragList: type[] = reactive<type[]>([{ name: "单行文本", id: 1, element: 'Input' },{ name: "多行文本", id: 2, element: 'Textarea' },{ name: "计数器", id: 3, element: 'InputNumber' },{ name: "单选框组", id: 4, element: 'Radio' },
])const widgetList = reactive<type[]>([])
//  A组
<draggable :list="dragList" ghost-class="ghost" :force-fallback="true" :group="{ name: 'list', pull: 'clone' }":sort="false" itemKey="id"><template #item="{ element }"><div class="item move"><label class="move">{{ element.name }}</label></div></template></draggable>// B组<draggable :list="widgetList" ghost-class="ghost" itemKey="id" :force-fallback="true" group="list":fallback-class="true" :fallback-on-body="true" class="drag-content"><template #item="{ element }"><div class="item move"><label class="move title">{{ element.name }}</label><div> <el-input v-model="input" placeholder="Please input" v-if="element.element === 'input'" /></div><div><el-input v-model="textarea" :rows="2" type="textarea" placeholder="Please input"v-if="element.element === 'textarea'" /> </div></div></template></draggable>

点击控件拖过去,就可以实现如下的效果,如果不想要标题,可以把label部分去掉,其他控件如法炮制即可:

在组件数量少的时候,可以这么做,但数量多时,建议使用component标签来映射

(1)先更改一下文件的结构

(2)写一个公共的函数去返回当前widgets文件夹下的所有文件

// getWidget.tsconst gets = {} as any 
const modules = import.meta.glob('./*.vue', {eager:true})
for (let each in modules) {const name = (modules[each] as any).default.__namegets[name] = (modules[each] as any).default
}console.log(gets);export default gets

也可使用globEager方法,编译器会报错:函数已经弃用,不过不影响使用。

(3)分别把每个组件的部分写好

// Input.vue
<template><div><el-input v-model="input" placeholder="Please input"  /></div>
</template><script lang="ts" setup>const input=ref('')
</script><style lang="less" scoped></style>

(4)使用component标签映射

<draggable :list="widgetList" ghost-class="ghost" itemKey="id" :force-fallback="true" group="list":fallback-class="true" :fallback-on-body="true" class="drag-content"><template #item="{ element }"><div class="item move"><label class="move title">{{ element.name }}</label><div><component :is="getWidget(element.element)"></component></div></div></template></draggable>// 使用函数映射<script lang="ts" setup>
import draggable from 'vuedraggable'
//要注意导入
import getName from './widgets/getWidget'const getWidget = (name: string) => {
//写的时候,组件的起名一定要与dragList中的element名字一模一样,不然会映射不上return getName[name]
}

(5)最终效果

成功实现!


http://chatgpt.dhexx.cn/article/Xle2ZmBd.shtml

相关文章

vue的拖拽插件: vue.draggable

中文文档地址: vue.draggable中文文档 - itxst.comVue.Draggable是一款基于Sortable.js实现的vue拖拽插件。支持移动设备、拖拽和选择文本、智能滚动&#xff0c;可以在不同列表间拖拽、不依赖jQuery为基础、vue 2过渡动画兼容、支持撤销操作&#xff0c;总之是一款非常优秀的…

react-draggable实现拖拽详解

react-draggable 属性常用属性属性列表 事件列表举例首先安装 react-draggable实现移动 希望小编写的能够帮助到你&#x1f618; 属性 常用属性 属性默认值介绍axisxhandle拖动的方向&#xff0c;可选值 x ,y,bothhandle无指定拖动handle的classposition无handle的位置&#…

draggable拖拽组件使用

项目开发中需要用到拖拽组件&#xff0c;因为前端技术框架是vue&#xff0c;这里就使用了vue的一款拖拽插件vue.draggable&#xff0c;一般基本的需求都能满足&#xff0c;这里使用了多个draggable嵌套&#xff0c;达到两级之前相互拖拽的功能。 以下是类似teambition的效果图…

原生JS的拖拽属性draggable(详解)

摘要 作为h5新增的属性draggable&#xff0c;它能够给与一切的html元素拖动的效果。而在这个属性之下&#xff0c;也有着关于拖动效果的各个方法。 而这一篇文章&#xff0c;主要就是说一下关于draggable属性的使用以及工作场景。 1.了解draggable属性的使用 对我来讲&#…

EasyUI基础入门之Draggable(拖拽)

前面学习了easyui基础的解析器,加载器。对于他们入门阶段我们只需简单的了解下即可&#xff0c;毕竟先阶段并不会太过深入。接下来根据easyui官网文档的顺序安排学习下Draggable插件。 Draggable是什么 Draggable是easyui中用于实现拖拽功能的一个插件。利用它&#xff0c;我们…

jts-core 使用说明(二)

jts-core 使用说明 示例代码库 JTS源码底层使用说明&#xff0c;通过一下章节介绍说明 层次结构 org.locationtech.jts: algorithm - 算法包jts-io-common - I/O classes for open spatial formatsgeom - geom基础包geom.prep - 对适当准备的几何图形执行优化的几何操作类e…

java jts获取线上任意一点到起点的距离

java jts获取线上任意一点到起点的距离 近期项目要求计算某段公路上一辆车的运行轨迹&#xff0c;通过路上的设备实时获取车辆的经纬度信息并发送到后台接收。 抽象出来就是获取线上任意一点到起点的距离&#xff0c;按照一定每秒一次的频率去计算就获取该点的运动轨迹了。 主要…

JTS-Geometry 使用说明(五)

org.locationtech.jts.geom.Geometry 使用说明 示例代码库 Geometry 经纬度操作类 Geometry类继承关系 说明 平面、线性几何操作抽象类 提供的相关方法: 1.基础方法&#xff1a; 1.1 getLength:获取长度&#xff0c;线几何返回点与点之间的长度之和&#xff1b;闭合几何返回…

JAVA使用JTS 判断坐标点是否在坐标多边形内部

JAVA使用JTS 判断坐标点是否在坐标多边形内部 思路Geometry之间的关系API及参考博客代码依赖工具类测试类 思路 判断坐标点是否在坐标多边形内部&#xff0c;首先不能直接计算坐标点&#xff0c;是需要字符串坐标点转化为地理空间数据Geometry&#xff0c;然后使用JTS包中提供…

JTS学习笔记

JTS学习笔记 基础的类 Geometry geom对象Coordinate坐标类Point Point对象MultiPoint 基本对象MultiPoint等等GeometryFactory工厂对象PreparedGeometryFactoryPreparedGeometry 几何对象Geometry public abstract class Geometry implements Cloneable, Comparable, Seria…

JTS-Angle GIS几何角度计算使用说明(十八)

org.locationtech.jts.algorithm.Angle 角度计算使用说明 示例代码库 Angle 角度计算 1.Angle.angle(p0,p1) public static double angle(Coordinate p0, Coordinate p1) {double dx p1.x - p0.x;double dy p1.y - p0.y;return Math.atan2(dy, dx); }返回与x轴正方向的夹…

java jts_Java Topology Suite (JTS)与空间数据模型

JTS是Java的处理地理数据的API&#xff0c;它提供以下功能&#xff1a; 实现了OGC关于简单要素SQL查询规范定义的空间数据模型 一个完整的、一致的、基本的二维空间算法的实现&#xff0c;包括二元运算(例如touch和overlap)和空间分析方法(例如intersection和buffer) 一个显示的…

java jts点到面的距离_jts-空间索引

前言&#xff1a; 如果您对JTS这三个词还是没有一个概念&#xff0c;那么推荐您关注一下sinoly的博客。这个我能够找到为数不多的关于jts的中文资料。 http://www.blogjava.net/sinoly/archive/2007/02/09/99042.html 下面这段话就是摘抄自sinoly老兄的博客&#xff1a; ......…

JTS Geometry关系判断和分析

关系判断 Geometry之间的关系有如下几种&#xff1a; 相等(Equals)&#xff1a; 几何形状拓扑上相等。 脱节(Disjoint)&#xff1a; 几何形状没有共有的点。 相交(Intersects)&#xff1a; 几何形状至少有一个共有点&#xff08;区别于脱节&#xff09; 接触(Touches)&a…

JTS Geometry用例分析

微信搜索&#xff1a;“二十同学” 公众号&#xff0c;欢迎关注一条不一样的成长之路 拓扑关系 GeometryTest import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import…

JTS 笔记

简介 JTS由加拿大的VividSolutions公司开发&#xff0c;是一个用Java语言描述的几何拓扑套件&#xff0c;遵循OpenGIS的Simple Feature Specification&#xff0c;封装了2D几何类型和非常多的空间分析操作&#xff0c;而且包含了不少常见的计算几何算法实现。     JTS被广泛…

jts 简介、中文文档、中英对照文档 下载

jts 文档 下载链接&#xff08;含jar包、源码、pom&#xff09; 组件名称中文-文档-下载链接中英对照-文档-下载链接jts-1.13.jarjts-1.13-API文档-中文版.zipjts-1.13-API文档-中英对照版.zip jts 简介 JTS拓扑套件 JTS拓扑套件是一个用于建模和操作二维线性几何的API。它…

GeoTools——JTS的相关介绍和操作

GeoTools——JTS的相关介绍&#xff08;一&#xff09; JTS拓扑套件是GeoTools用于提供Geometry数据结构的实现&#xff0c;Geometry主要是指几何形状。 想要使用geoTools——JTS相关的操作可以导入以下的依赖<properties><geotools.version>17.1</geotools.ver…

java topo: 开源jtopo框架

java web 非本人研究方向&#xff0c;只是作为拓展知识涉猎范围 原文链接&#xff1a;http://www.jtopo.com/index.html jTopo是什么? jTopo&#xff08;Javascript Topology library)是一款完全基于HTML5 Canvas的关系、拓扑图形化界面开发工具包。 jTopo关注于数据的图形展…

JTopo踩坑记 -- React项目中使用JTopo

JTopo踩坑记 – React项目中使用JTopo JTopo-in-node & JTopo 最近实习公司一个项目需要绘制电网的拓扑图&#xff0c;大致要求的效果如下&#xff1a; 首先想到的是Echarts和d3&#xff0c;因为这个项目其他图表都是使用的Echarts&#xff0c; 但是在Echarts的官方示例…