实现小程序拖拽排序

实现效果


这是最近我做的一个需求,由于产品项目模块众多,达近80个模块,所以有了这个模块管理排序的需求,得益于小程序自带的组件movable-view(基础库 1.2.0 开始支持),使得拖拽这一交互效果的实现变得优雅。在这里记录下写这个模块的一些心得

核心方法

有三个核心方法,分别是bindchange事件(movable-view自带事件,类似于touchmove事件),touchend事件,touchstart事件
核心代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
touchStart(index, fatherIndex) {
this.clientX = null
this.clientY = null
},
touchMoving(index, fatherIndex, event) {
this.clientX = event.detail.x + (this.moveAreaWidth / 4 / 2) //this.moveAreaWidth每个modal
this.clientY = event.detail.y + ITEM_HEIGHT / 4
},
touchEnd(index, fatherIndex) {
if (this.clientX && this.clientY) {
const row = Math.floor(this.clientY / (ITEM_HEIGHT / 2))
const column = Math.floor(this.clientX / (this.moveAreaWidth / 4))
const newIndex = row * 4 + column
index == newIndex ? this.hasChangedSort = false : (this.hasChangedSort = true,this.handleDragEnd(index, fatherIndex, newIndex))
}
}

在这里,touchStart事件初始化每次拖拽后设定的clientX,clientX
touchmove事件中需要处理这样一件事,根据每个模块的高度以及宽度(需要通过小程序APIwx.createSelectorQuery计算得出)实时计算出落点所在的x,y坐标,最后touchend事件计算出x,y坐标所对应的行列数,根据行列数计算出当前模块所在对应数组中的索引序列(handleDragEnd方法),在data数据源数组中替换两个模块数据的索引下标

遇到的问题

由于直接改变索引下标会造成瞬闪现象,就是拖拽完成后模块会先在原来位置闪现一下再回到拖拽后的位置,这是因为操作数据会直接改变视图,所以我们需要一个延时操作$nextTick,在这个延时方法中去操作新位置模块的x,y坐标,就可以解决这个问题