手册版本 V6.0
竖向拖动排序介绍
01. 封装为组件在使用时反而不灵活,所以使用页面布局实现;
02. 利用手指事件完成拖拽及拖拽完成后的数据排序功能;
03. 因 weex 底层原因暂不支持,请使用 vue 页面完成此功能;
核心事件
01. onLoad : 模拟 api 请求,并补全数据属性
02. longtap : 长按后才能进行拖拽
03. thStart : 手指滑动开始
04. thMove : 手指滑动
05. thEnd : 拖拽完成对数据进行重新排序
兼容平台
演示代码
<template>
<gui-page>
<template v-slot:gBody>
<view
style="margin-top:66rpx;"
class="gui-padding-x">
<text class="gui-h6 gui-color-gray">拖动排序</text>
</view>
<view
class="gui-bg-white gui-dark-bg-level-3 gui-margin-top">
<view
class="drag-list"
@touchmove.stop.prevent="thMoveS">
<view
v-for="(item, index) in lists"
:key="index"
:style="{
transform:'translateY('+lists[index].y+'px) translateZ('+(index == movingIndex ? '120px' : '0px' )+')',
position:lists[index].y != 0 ? 'absolute' : 'relative',
paddingTop:index==preIndex?'20px':'0',
opacity:index == movingIndex ? 0.9 : 1}"
@touchstart="thStart"
@touchmove="thMove"
@touchend="thEnd"
class="drag-list-item"
@longpress="longtap"
:data-index="index"
:id="'draglist'+index">
<view class="drag-list-order gui-color-gray">{{index + 1}}</view>
<image
:src="item.img"
class="drag-list-img"
mode="widthFix"></image>
<view class="drag-list-content gui-primary-text">{{item.title}}</view>
<view
class="drag-list-icon gui-icons"
:class="[index==movingIndex?'gui-primary-color':'gui-color-gray']"></view>
</view>
</view>
</view>
</template>
</gui-page>
</template>
<script>
import graceJS from '@/Grace6/js/grace.js';
var demoData = [
{img:'http://img4.imgtn.bdimg.com/it/u=552119130,3001255642&fm=26&gp=0.jpg',title:"小明 0"},
{img:'http://img2.imgtn.bdimg.com/it/u=3428383444,2828052422&fm=26&gp=0.jpg', title:"小米 1"},
{img:'http://img2.imgtn.bdimg.com/it/u=1972994033,181763631&fm=26&gp=0.jpg', title:"美美 2"},
{img:'http://img1.imgtn.bdimg.com/it/u=291222564,3369340489&fm=26&gp=0.jpg', title:"小牛 3"},
{img:'http://img3.imgtn.bdimg.com/it/u=3904304279,448031564&fm=26&gp=0.jpg', title:"小林 4"}
];
export default {
data(){
return {
lists : [],
movingIndex : -1,
preIndex : -1,
dragTimer : null,
moveStartY : 0,
pageScrollTop : 0,
pageScrollTimer : null
}
},
onLoad : function(){
// 模拟 api 请求
setTimeout(()=>{
// api 数据内没有 y 坐标记录循环补充
for(let i = 0; i < demoData.length; i++){
demoData[i].y = 0;
demoData.splice(i,1,demoData[i]);
}
this.lists = demoData;
});
},
onPageScroll:function(e){
clearTimeout(this.pageScrollTimer);
this.pageScrollTimer = setTimeout(()=>{
this.pageScrollTop = e.scrollTop;
}, 200);
},
methods:{
// 长按后才能进行拖拽
longtap:function(e){
this.movingIndex = Number(e.currentTarget.dataset.index);
this.preIndex = -1;
},
thStart:function(e){
this.moveStartY = Number(e.touches[0].pageY);
},
// 移动进行拖拽
thMove : function(e){
if(this.movingIndex == -1){return ;}
var moveY = Number(e.touches[0].pageY) - this.moveStartY;
if(moveY < -30 && this.preIndex < this.movingIndex){moveY -= 20;}
this.lists[this.movingIndex].y = moveY;
this.lists.splice(this.movingIndex, 1, this.lists[this.movingIndex]);
this.moveBase();
},
thMoveS : function (e) {
if(this.movingIndex == -1){
var moveY = Number(e.touches[0].pageY) - this.moveStartY;
moveY *= -1;
this.pageScrollTop = this.pageScrollTop + moveY;
if(this.pageScrollTop < 0){this.pageScrollTop = 0;}
uni.pageScrollTo({
scrollTop : this.pageScrollTop,
duration : 0
});
}
},
moveBase : function () {
if(this.dragTimer != null){return ;}
this.dragTimer = 1;
setTimeout(()=>{this.dragTimer = null;}, 100);
graceJS.selectAll('.drag-list-item', (resIn)=>{
if(!resIn){return ;}
graceJS.select('#draglist'+this.movingIndex, (res)=>{
if(!res){return ;}
// 上下移动
var currentTop = res.top;
for(let i = 0; i < resIn.length; i++){
if(i != this.movingIndex){
var top = resIn[i].top;
if(currentTop < top){
this.preIndex = i;
break;
}else{
this.preIndex = this.lists.length;
}
}
}
});
});
},
// 拖拽完成 完成后 lists 数组会被重新排序
thEnd : function (e) {
if(this.movingIndex == -1 || this.preIndex == -1){
this.movingIndex = -1;
this.preIndex = -1;
return ;
}
this.lists[this.movingIndex].y = 0;
var dragData = JSON.stringify(this.lists);
dragData = JSON.parse(dragData);
if(this.movingIndex > this.preIndex){
var dropOrder = dragData.splice(this.movingIndex, 1);
dragData.splice(this.preIndex, 0 , dropOrder[0]);
}else{
dragData.splice(this.preIndex, 0 , dragData[this.movingIndex]);
dragData.splice(this.movingIndex, 1);
}
this.$nextTick(()=>{
this.movingIndex = -1;
this.$nextTick(()=>{
this.preIndex = -1;
this.$nextTick(()=>{
this.lists = dragData;
this.$nextTick(()=>{
this.movingIndex = -1;
this.preIndex = -1;
})
})
});
});
}
}
}
</script>
<style scoped>
.drag-list{padding-left:25rpx; transform-style:preserve-3d; position:relative;}
.drag-list-item{display:flex; flex-direction:row; flex-wrap:nowrap; align-items:center;}
.drag-list-order{width:50rpx; text-align:center; margin:0 10px; flex-shrink:0; font-size:36rpx; font-style:italic;}
.drag-list-icon{width:60rpx; line-height:60rpx; flex-shrink:0; font-size:36rpx;}
.drag-list-img{width:66rpx; height:66rpx; flex-shrink:0; font-size:36rpx; border-radius:60rpx;}
.drag-list-content{width:700rpx; line-height:120rpx; font-size:28rpx; margin-left:20rpx;}
</style>