一、安装插件Sortable.js
npm i sortablejs --save
或者
yarn add sortablejs --save
二、引入
/* 引入插件 */
import Sortable from "sortablejs";
三、拖拽区html
key取的随机数--目的为了每次拖拽后重新渲染
id="fieldCtr"
取的这个dom一定是最外围的元素(拖拽区域),不能放到循环体内
<!-- 未显示字段 -->
<div id="fieldCtr" :key="randomKey">
<div v-for="item in list" :key="item.label">
<div>{{ item.label }}</div>
</div>
</div>
data() {
return {
// 重排key
randomKey: Math.random(),
};
},
四、初始化
watch: {
// 数据发生变化--都需要重新构建sortable
list: {
handler(list) {
// list为0 无法拖拽
if (list.length === 0) return;
// 重新构建sortable
this.reDrawer();
},
immediate: true,
},
},
五、拖拽事件
/**
* 拖拽事件
*/
drag() {
const _this = this;
const wrapperTr = document.getElementById("fieldCtr");
this.sortable = Sortable.create(wrapperTr, {
animation: 180,
delay: 0,
onEnd: (evt) => {
// 跳过显示的列数量,如开头我们用了一个多选框,h和序号
const oldItem = this.list[evt.oldIndex];
this.list.splice(evt.oldIndex, 1);
this.list.splice(evt.newIndex, 0, oldItem);
},
});
},
// 重排
reDrawer() {
this.randomKey = Math.random()
this.$nextTick(() => {
this.drag();
});
},
六、属性
- group:
string: 用于定义多组列表进行交互时进行关联的名称;
// or
object:{ name, pull, put }
name:同上面 string;
// 定义从容器列表移除的设置,可选值为:true/false/'clone'/function
// 如果为 false,不能拖动容器子项添加到其他容器内,但可以在本容器内进行拖拽排序
pull: true,
// 定义向容器列表放置列表单元的的设置,可选值为true/false/['foo','bar']/function
// 其中 ['foo','bar']:这个可以是一个字符串或者是字符串的数组,代表的是group配置项里定义的name值
// 如果为 false,不允许其他容器的子项拖拽至当前容器内,但可以在本容器内进行拖拽排序
put: true,
- sort:boolean 定义列表单元是否可以在列表容器内进行拖拽排序。
- disabled:boolean 定义当前容器单元 sortable 对象是否可用。
- animation:number 单位:ms,定义排序过程中动画的时间。
- handle:selector 格式:简单的选择器字符串,比如 class;使得在容器内,任意层级的子元素,只有存在指定的 class 的元素上,才能够拖动。
handle: ".drag",
- filter:selector 格式:简单的选择器字符串,比如 class;定义哪些列表单元不能进行拖放,可设置为多个选择器,中间用“,”分隔。
- draggable:selector 格式:简单的选择器字符串,比如 class;定义哪些列表单元可以进行拖拽。
- dragClass:selector 格式 class 选择器,定义拖拽时,跟随鼠标移动的预览元素样式。
- ghostClass:selector 格式 class 选择器,在拖动元素时,放置位置的影子设置样式。
- chosenClass:selector 格式 class 选择器,当选中列表单元时会给该单元增加一个 class。
- scroll:boolean 默认为true,当排序的容器是个可滚动的区域,拖放可以引起区域滚动。
七、事件
// 列表单元被选中的回调函数
onChoose(evt) {
console.log('onChoose: 列表单元被选中!');
},
// 列表单元拖动开始的回调函数
onStart(evt) {
console.log('onStart: 列表单元拖动开始的回调函数!');
},
// 容器列表单元,在拖放结束后的回调函数
onEnd(evt) {
console.log('onEnd: 列表单元拖放结束后的回调函数!');
},
// 其他列表单元添加到本列表容器的回调函数
onAdd(evt) {
console.log('onAdd: 其他列表单元添加到本列表容器的回调函数');
},
// 列表单元在列表容器中的排序发生变化后的回调函数
onUpdate(evt) {
console.log('onUpdate: 列表单元在列表容器中的排序发生变化后的回调函数');
},
// 列表元素移到另一个列表容器成功后的回调函数
onRemove(evt) {
console.log('onRemove: 列表元素移到另一个列表容器的回调函数');
},
// 试图选中一个被 filter 过滤的列表单元的回调函数
onFilter(evt) {
console.log('onFilter: 试图选中一个被filter过滤的列表单元的回调函数');
},
// 当移动列表单元在一个列表容器中或者多个列表容器中的回调函数
onMove(evt, originalEvt) {
console.log('onMove: 当移动列表单元在一个列表容器中或者多个列表容器中的回调函数');
},
// 当创建一个列表单元副本的时候的回调函数
onClone(evt) {
console.log('onClone: 当创建一个列表单元副本的时候的回调函数');
},
// 用于传递数据,在容器单元按住拖动时触发
setData: function (/** DataTransfer */dataTransfer, /** HTMLElement*/dragEl) {
dataTransfer.setData('Text', dragEl.textContent); // `dataTransfer` object of HTML5 DragEvent
},
八、事件对象evt的属性介绍
to:HTMLElement--移动到的列表容器
from:HTMLElement--来源的列表容器
target:HTMLElement--来源的列表容器
item:HTMLElement--被移动的列表单元
clone:HTMLElement--副本的列表单元
oldIndex:number/undefined--在列表容器中的原序号
newIndex:number/undefined--在列表容器中的新序号
pullMode:默认是 undefined,当项目位于另一个可排序列表中时,如果操作克隆,值为 clone,如果是移动,只为 true。
九、方法
sortable 是构造函数Sortable创建出来的实例
9.1. option:设置/获取配置信息
sortable.option('sort', false); // 设置
sortable.option('sort'); // 获取
9.2. toArray:获取 序列化可排序的列表单元的 data-id
var order = sortable.toArray(); // ['36h', '36i', '36j', '36k', '36l', '36m']
9.3. sort:根据列表单元的 data-id 进行排序
sortable.sort(order.reverse()); // 重新排序
9.3. destory:销毁容器排序:
sortable.destroy(); // 销毁容器排序