目录
VueDraggablePlus的使用
插件API
group属性 拖拽分组
delay 响应时间
disabled 启用禁用
scroll 是否允许滚动
animation 过渡效果
handle 鼠标在指定元素上才允许拖动
filter 排除步允许拖动的元素
chosenClass 选中元素的样式
ghostClass 目标位置占位符的样式
clone 拷贝实现常用菜单功能
dragClass 拖拽项类名
更多api
事件函数
move 自定义控制那些元素可以拖拽或不允许拖拽并控制是否允许停靠
add 从A组拖动到B组完成的事件
start开始拖动时的事件
remove 元素从列表中移除进入另一个列表
end 拖拽结束
update 元素顺序更新时触发
sort 列表的任何更改都会触发
Move 拖拽移动的时候触发
Change 拖拽元素改变位置时触发
Clone 克隆一个元素时触发
Choose 元素被选中
使用案例
基础使用
组件方式
函数方式
指令方式
双列表拖拽排序
克隆
表格拖拽
表格行拖拽
表格列拖拽
嵌套
个人应用
遇见的问题及总结
拖拽事件与点击事件冲突
获取拖动时产生新的新数组
拖拽元素在新数组的上一位元素出现效果顺序出错
拖拽元素的样式出问题,出现鼠标点击部分有内容,远离鼠标部分逐渐透明
VueDraggablePlus的使用
安装VueDraggablePlus插件(拖拽排序模块,支持 Vue>=v3 或 Vue >=2.7)
npm install vue-draggable-plus
插件API
group属性 拖拽分组
group 拖拽分组多组之间相互拖拽,可以实现不同数组之间相互拖拽。比如group都为itxst的组之间可以相互拖动,本文例子中A列和B列可以相互拖动,但是无法拖到C列。
//设置方式一,直接设置组名
group:'itxst'
//设置方式,object,也可以通过自定义函数function实现复杂的逻辑
group:{
name:'itxst',//组名为itxst
pull: true|false| 'clone'|array|function,//是否允许拖出当前组
put:true|false|array|function,//是否允许拖入当前组
}
//字符串类类型用法
//直接设置字符串类型的组名,相同名称的组就可以相互拖拽
<VueDraggablev-model="arr1" group="itxst">
<transition-group>
<div class="item" v-for="item in arr1" :key="item.id">
{
{ item.name }}
</div>
</transition-group>
</VueDraggable>
<VueDraggable v-model="arr2" group="itxst">
<transition-group>
<div class="item" v-for="item in arr1" :key="item.id">
{
{ item.name }}
</div>
</transition-group>
</VueDraggable>
//Object类型用法
//可以比字符串名称更精确的控制拖入拖出
<VueDraggablev-model="arr1" :group="groupA">
<transition-group>
<div class="item" v-for="item in arr1" :key="item.id">
{
{ item.name }}
</div>
</transition-group>
</VueDraggable>
<VueDraggablev-model="arr2" :group="groupB">
<transition-group>
<div class="item" v-for="item in arr1" :key="item.id">
{
{ item.name }}
</div>
</transition-group>
</VueDraggable>
<script>
export default {
data() {
return {
//group属性对象
groupA: {
name: "itxst",
pull: true, //可以拖出
put: true, //可以拖入
},
groupB: {
name: "itxst",
pull: true,
put: true,
},
};
},
};
</script>
//自定义函数用法
//通过自定义函数可以精确的控制是否允许拖入拖出
<VueDraggablev-model="arr1" :group="groupA">
<transition-group>
<div class="item" v-for="item in arr1" :key="item.id">
{
{ item.name }}
</div>
</transition-group>
</VueDraggable>
<VueDraggable v-model="arr2" :group="groupB">
<transition-group>
<div class="item" v-for="item in arr1" :key="item.id">
{
{ item.name }}
</div>
</transition-group>
</VueDraggable>
<script>
export default {
data() {
return {
//group属性对象
groupA: {
name: "itxst",
put: true, //可以拖入
pull: () => {
if (this.arr1.length <= 3) {
this.message = "元素小于等于3不允许再拖拽了";
}
return this.arr1.length > 3;
},
},
groupB: {
name: "itxst",
pull: true,
put: true,
},
};
},
};
</script>
delay 响应时间
鼠标按下后等待n秒才允许拖动,此属性可以一定程度上防止误触操作,比如设置delay为1000表示按下一秒后才允许拖动。
<template>
<div>
<!--使用draggable组件-->
<div class="itxst">
<div class="col">
<div class="title" >按下一秒后才允许拖动</div>
<VueDraggable v-model="arr1" delay="1000" group="site" animation="300" dragClass="dragClass" ghostClass="ghostClass" chosenClass="chosenClass" @start="onStart" @end="onEnd">
<transition-group>
<div class="item" v-for="item in arr1" :key="item.id">{
{item.name}}</div>
</transition-group>
</VueDraggable>
</div>
</div>
</div>
</template>
<style scoped>
/*定义要拖拽元素的样式*/
.ghostClass{
background-color: blue !important;
}
.chosenClass{
background-color: red !important;
opacity: 1!important;
}
.dragClass{
background-color: blueviolet !important;
opacity: 1 !important;
box-shadow:none !important;
outline:none !important;
background-image:none !important;
}
.itxst{
margin: 10px;
}
.title{
padding: 6px 12px;
}
.col{
width: 40%;
flex: 1;
padding: 10px;
border: solid 1px #eee;
border-radius:5px ;
float: left;
}
.col .col{
margin-left: 10px;
}
.item{
padding: 6px 12px;
margin: 0px 10px 0px 10px;
border: solid 1px #eee;
background-color: #f1f1f1;
}
.item:hover{
background-color: #fdfdfd;
cursor: move;
}
.item .item{
border-top:none ;
margin-top: 6px;
}
</style>
<script>
//导入draggable组件
import draggable from 'vuedraggable'
export default {
//注册draggable组件
components: {
draggable,
},
data() {
return {
drag:false,
//定义要被拖拽对象的数组
arr1:[
{id:1,name:'www.itxst.com'},
{id:2,name:'www.jd.com'},
{id:3,name:'www.baidu.com'},
{id:4,name:'www.taobao.com'}
]
};
},
methods: {
//开始拖拽事件
onStart(){
this.drag=true;
},
//拖拽结束事件
onEnd() {
this.drag=false;
},
},
};
</script>
disabled 启用禁用
通过disabled属性实现开启或禁用vue.draggable的拖拽效果。(disable=true禁用)
<VueDraggable
ref="el"
v-model="list"
:disabled="true"
:animation="150"
ghostClass="ghost"
class="flex flex-col gap-2 p-4 w-300px h-300px m-auto bg-gray-500/5 rounded"
@start="onStart"
@update="onUpdate"
>
```
</VueDraggable>
scroll 是否允许滚动
vue.draggable scroll属性容器有滚动条时是否允许滚动及当父容器元素有滚动条时是否允许拖动。
属性名称 | 说明 |
---|---|
scroll | 默认为true,容器有滚动条时是否允许拖动到被隐藏的区域 |
animation 过渡效果
通过animation属性设置vue.draggable过渡效果,这样拖动时过渡位置就不会显的太生硬。
handle 鼠标在指定元素上才允许拖动
当鼠标落在handle指定的元素上面时才允许拖动,如下面的例子只能点击类名为.handle的区域才能拖动,点击其他区域则无法拖动。
<VueDraggable
v-model="list"
:animation="150"
handle=".handle"
class="flex flex-col gap-2 p-4 w-300px bg-gray-500/5 rounded"
>
</VueDraggable>
filter 排除步允许拖动的元素
如果你想设置某个元素或对象不允许拖动拖拽把这些元素的样式名称设置到filter属性即可,本文将实现包含forbid样式的元素将无法拖动,第一行无法拖动,也无法拖动到第一行,用到filter和move属性。
<VueDraggable v-model="arr1" filter=".forbid" animation="300" :move="onMove">
<transition-group>
<div :class="item.id==1?'item forbid':'item'" v-for="item in arr1" :key="item.id">{
{item.name}}</div>
</transition-group>
</VueDraggable>
//包含forbid样式的元素将无法拖动,即第一行无法拖动,也无法拖动到第一行
chosenClass 选中元素的样式
设置选中元素的样式,可以通过自定义样式来方便的区分出那个元素被选中。即鼠标按下去到拖动之前的样式状态。
<VueDraggable v-model="arr1" group="itxst" ghostClass="ghost" chosenClass="chosen" filter=".forbid" animation="300" :move="onMove">
.chosen即是鼠标选中的子元素的样式
ghostClass 目标位置占位符的样式
目标位置占位符的样式及需要停靠位置的样式。即拖动过程中被选中的元素的样式。
clone 拷贝实现常用菜单功能
clone拷贝实现常用菜单功能,从一个拖拽组拖动到另外一个组而原来的那种组的元素不移除。
属性 | 说明 |
---|---|
clone | :options="{group:{name: 'itxst',pull:'clone'},sort: true}" group属性的clone表示允许克隆被拖动的元素> |
move | move事件用来控制那个元素不允许被拖拽和获取当前拖动元素的对象 |
end | end拖拽结束事件,用来判断是否已经存在对象 |
<template>
<div>
<!--使用draggable组件-->
<div class="itxst">
<div style="padding-left:6px">clone例子,左边往右边拖动试试看</div>
<div class="col">
<VueDraggable v-model="arr1" @end="end1" :options="{group:{name: 'itxst',pull:'clone'},sort: true}" animation="300" :move="onMove">
<transition-group>
<div :class="item.id==1?'item forbid':'item'" v-for="item in arr1" :key="item.id">{
{item.name}}</div>
</transition-group>
</VueDraggable>
</div>
<div class="col">
<VueDraggable v-model="arr2" @end="end2" group="itxst" animation="300" :move="onMove">
<transition-group>
<div :class="item.id==12?'item2 forbid':'item2'" v-for="item in arr2" :key="item.id">{
{item.name}}</div>
</transition-group>
</VueDraggable>
</div>
</div>
</div>
</template>
<script>
//导入draggable组件
import draggable from 'vuedraggable'
export default {
//注册draggable组件
components: {
draggable,
},
data() {
return {