1、与vue配套的拖拽组件vuedraggable
安装引入
安装 yarn add vuedraggable 或 npm install vuedraggable或 cnpm install vuedraggable
引入 import vuedraggable from 'vuedraggable';
连接引入
<script src="http://www.itxst.com/package/vue/vue.min.js"></script><script src="http://www.itxst.com/package/sortable/Sortable.min.js"></script><script src="http://www.itxst.com/package/vuedraggable/vuedraggable.umd.min.js"></script>
因为vuedraggable是基于Sortable做了vue处理的封装,所以必须先引入Sortable.min.js。
安装了vuedraggable可以直接使用Sortable.js,不用再安装。
例子
<template>
<vuedraggable v-model="list">
<transition-group>
<div v-for="item in list" :key="item" class="item">
<p>{{item}}</p>
</div>
</transition-group>
</vuedraggable>
</template>
<script>
import vuedraggable from 'vuedraggable';
export default {
name: 'HelloWorld',
components: {vuedraggable},
data() {
return {
list: [1,2,3,4,5,6]
}
},
</script>
<transition-group></transition-group> //用transition-group包裹起来会增加拖拽动画。
常用属性及说明
属性名称
说明
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
滚动速度
优点:简单,不需要过多的配置,组件自带双向绑定。
唯一缺点,有一个业务需求,需要三列随意交换,使用element组件,发现嵌套在element ui内部拖拽无法使用,也可能是哪里配置出错了。我认为element UI与 vuedraggable 不兼容。
2、Sortable.js
为了完成上面的业务需求使用了Sortable.js插件解决需求。
安装引入
安装 npm/cnpm install sortablejs --save 或yarn add sortablejs --save引入 import Sortable from 'sortablejs';
连接引入 <script src="http://www.itxst.com/package/sortable/sortable.min.js"></script>
使用方式
<ul calss="drag-parent" row-key="id">
<li v-for="(item,index) in list" :key="item.index">
<li/>
<ul/>
//list 就省略了,有两点要注意
//1、父盒子要加row-key="id",不然会出现拖拽乱序,2、key的值不能是index,因为sortable 交换index值
不会交换,用index会出现乱序,必须用itm自带的唯一标识符。
sortVolunteer(){ //关键代码,行拖拽
const that = this;
this.$nextTick(()=>{
const wrapperTr = document.querySelector('.drag-parent') //父盒子
this.sortable = Sortable.create(wrapperTr, {
animation: 180,
delay: 0,
// 开始拖拽的时候,行拖拽
onEnd: ({newIndex,oldIndex}) => {
let collegeIndex = this.index
const targetRow = that.collegeList[collegeIndex].splice(oldIndex, 1)[0] //collegeList[collegeIndex] 要交换的数组
that.collegeList[collegeIndex].splice(newIndex, 0, targetRow)
const list = JSON.parse(JSON.stringify(this.collegeList)); // that.collegeList 绑定的总数组
this.collegeList = [];
this.$nextTick(()=>{
this.collegeList = list;
this.sortVolunteer(); // 为了解决element兼容问题这里必须在调用一次
//sortVolunteer 不然会出现乱序,不是element不用这些步骤。
});
},
})
});
},
列拖拽
columnDrop() {
if(this.sortable) this.sortable.destroy();
this.$nextTick(()=>{
const wrapperTr = document.querySelector('.tablewrap tr')
this.sortable = Sortable.create(wrapperTr, {
animation: 180,
delay: 0,
filter:'.undragble',
group:{name:'shared',pull:true,put:true},
draggable:'.share', //控制哪些列不可拖拽
// 开始拖拽的时候
onEnd: evt => {
const oldItem = this.col[evt.oldIndex];
this.col.splice(evt.oldIndex, 1);
this.col.splice(evt.newIndex, 0, oldItem);
const list = JSON.parse(JSON.stringify(this.list)); //深拷贝
this.list = []; // that.list 绑定的总数组
this.$nextTick(()=>{
this.list = list;
this.columnDrop(); //重新执行一次
});
},
})
});
},
Sortable优点是兼容所有的框架,例如jQuery,缺点是配置非常麻烦,而且sortVolunteer函数得自己写,里面的数据变化容易出错,建议优先使用vuedraggable。
Sortable 中文翻译网址www.sortablejs.com/ 具体配置项可以去参考。