「这是我参与11月更文挑战的第9天,活动详情查看: 2021最后一次更文挑战 」
Vue.Draggable是一款基于Sortable.js实现的vue拖拽插件。支持移动设备、拖拽和选择文本、智能滚动,可以在不同列表间拖拽、不依赖jQuery为基础、vue 2过渡动画兼容、支持撤销操作,总之是一款非常优秀的vue拖拽组件。本篇将介绍如何搭建环境及简单的例子,使用起来特别简单对被拖拽元素也没有CSS样式的特殊要求。
NPM或yarn安装方式
yarn add vuedraggable
npm i -S vuedraggable
如果下面的属性说明未能完全看明白,请访问非vue版 sortable.js里面有更详细的例子。
属性名称 说明 group :group= "name",相同的组之间可以相互拖拽 sort :sort= "true",是否开启内部排序,如果设置为false,它所在组无法排序,在其他组可以拖动排序 delay :delay= "0", 鼠标按下后多久可以拖拽 touchStartThreshold 鼠标移动多少px才能拖动元素 disabled :disabled= "true",是否启用拖拽组件 animation 拖动时的动画效果,还是很酷的,数字类型。如设置animation=1000表示1秒过渡动画效果 handle :handle=".mover" 只有当鼠标移动到css为mover类的元素上才能拖动 filter :filter=".unmover" 设置了unmover样式的元素不允许拖动 draggable :draggable=".item" 那些元素是可以被拖动的 ghostClass :ghostClass="ghostClass" 设置拖动元素的占位符类名,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true chosenClass :ghostClass="hostClass" 被选中目标的样式,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true dragClass :dragClass="dragClass"拖动元素的样式,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true dataIdAttr dataIdAttr: 'data-id' forceFallback 默认false,忽略HTML5的拖拽行为,因为h5里有个属性也是可以拖动,你要自定义ghostClass chosenClass dragClass样式时,建议forceFallback设置为true fallbackClass 默认false,克隆的DOM元素的类名 allbackOnBody 默认false,克隆的元素添加到文档的body中 fallbackTolerance 拖拽之前应该移动的px scroll 默认true,有滚动区域是否允许拖拽 scrollFn 滚动回调函数 scrollSensitivity 距离滚动区域多远时,滚动滚动条 scrollSpeed 滚动速度
事件名称 说明 start 开始拖动时触发的事件 add 从一个数组拖拽到另外一个数组时触发的事件 remove 移除事件 update 拖拽变换位置时触发的事件 end 拖拽完成时的事件 choose 鼠标点击选中要拖拽元素时的事件 unchoose 选中后松开鼠标的事件 sort 位置变化时的事件 clone 从一个数组拖拽到另外一个数组时触发的事件和add不同,clone是复制了数组元素
我们的需求
原文档这块写的不清晰
从A区间可以往B区拖动
A区的数据不删除
A区不能往A区拖动
A区的数据需要经过处理,才能放到B
如何达到上面的需求呢,这里要用到 自定义控制
vue.draggable move 自定义控制那些元素可以拖拽或不允许拖拽并控制是否允许停靠
//move回调方法
onMove(e,originalEvent){
console.log(e);
console.log(originalEvent);
//false表示阻止拖拽
return true;
/** e对象结构注释
draggedContext: 被拖拽的元素
index: 被拖拽的元素的序号
element: 被拖拽的元素对应的对象
futureIndex: 预期位置、目标位置
relatedContext: 将停靠的对象
index: 目标停靠对象的序号
element: 目标的元素对应的对象
list: 目标数组
component: 将停靠的vue组件对象
A 拖拽组件配置
<vuedraggable
v-model="arr1"
:move="onMove"
:options="{ group: { name: 'site', pull: 'clone' }, sort: true }"
animation="300"
drag-class="dragClass"
ghost-class="ghostClass"
chosen-class="chosenClass"
@add="onAdd"
@start="onStart"
@end="onEnd"
<transition-group>
<div v-for="item in arr1" :key="item.id" class="item">
style="margin-bottom: 20px"
src="https://img3.bitautoimg.com/autoalbum/files/20190416/918/0333509185_6.png"
width="100px"
{{ item.name }}
</transition-group>
</vuedraggable>
B拖拽组件配置
<vuedraggable
v-model="arr2"
group="site"
animation="300"
@add="onAdd"
@start="onStart"
@end="onEnd"
<transition-group>
<div v-for="item in arr2" :key="item.id" class="item">
{{ item.name }}
</transition-group>
</vuedraggable>
methods: {
onMove(e, originalEvent) {
console.log(e, originalEvent, 'onMove')
// 停靠对象 如果停靠对象是A区,就拒绝掉
if (e.relatedContext.element.isConfig) return false
// 拖拽对象
// if (e.draggedContext.element.isConfig) return false
return true
以及data数据
data() {
return {
arr1: [
{ id: 1, isConfig: true, name: 'www.itxst.com' },
{ id: 2, isConfig: true, name: 'www.jd.com' },
{ id: 3, isConfig: true, name: 'www.baidu.com' },
{ id: 4, isConfig: true, name: 'www.taobao.com' },
arr2: [
{ id: 5, name: 'www.google.com' },
{ id: 6, name: 'www.msn.com' },
{ id: 7, name: 'www.ebay.com' },
{ id: 8, name: 'www.yahoo.com' },
PS:注意事项
A区组件添加 :options="{ group: { name: 'site', pull: 'clone' }, sort: true }"
其中的 name:site 指向B组件的group属性,表示clone到B 但是A不删除
在move方法中 e.relatedContext.element 代表停靠的数据对象,也就是B的元素,e.draggedContext.element 被拖拽的元素对象。 也就是A元素。然后开始处理A的数据