使用uniapp的movable-view在微信小程序端实现宫格拽动排序
前言:这是第一版,还有一些bug。如:拖拽后,不能实现dom上数据的更新,暂未想到合适的解决办法。
先放视频
拖拽排序1.0
<template>
<view class="sort-main">
<movable-area class="oper-imgs">
<movable-view
class="item"
v-for="(item,index) in controlsArray"
:key="item.id"
style="background-color: #fff;"
:x="item.x" :y="item.y"
direction="all"
@change="onChange"
@touchstart="moveStart($event, index)"
@touchend="moveEnd"
>{{index}}--{{item.id}}</movable-view>
</movable-area>
</view>
</template>
<script>
export default {
data() {
return {
controlsList:[
{id:1,img:'/static/image/uuu.png',down: 1,zhiding: 1,type:1},
{id:2,img:'/static/image/11.jpg',down: 0,zhiding: 1,type:1},
{id:3,img:'/static/image/22.gif',down: 999,zhiding: 0,type:1},
{id:4,img:'/static/image/uu.png',down: 20,zhiding: 0,type:1},
{id:5,img:'/static/image/25.jpg',down: 20,zhiding: 0,type:1},
],
containerSize: {width: '98vw',height: '98vh'},//容器大小
controlsSize: {width: 90,height: 90},//控件大小
// 控件列表
controlsArray: [],
// 每行最大存放的个数
maxWidthCount: 0,
// 控件的间距
margin: {
margin_x: 10,
margin_y: 10,
},
// 控件的数据
controlsPositionArray: [],
};
},
onShow() {
// 获取系统信息
this.systemInfo = uni.getSystemInfoSync();
// 获取控件列表
this.controlsArray = this.controlsList;
// 初始化控件的位置
this.controlsPositionArray = this.initControlsPosition(this.controlsList);
},
methods: {
/** 初始化各个控件的位置 */
initControlsPosition(list) {
// 用于返回出去的新数组
let tempArray = [];
// 每行最大存放的个数
this.maxWidthCount = parseInt(this.systemInfo.windowWidth / (this.controlsSize.width + this.margin.margin_x));
// 设置控件位置 - 这边多记录一个位置 之后会用到
for(let i = 0, j = 0, k = 0; i < list.length; i++) {
tempArray[i] = list[i]
tempArray[i].x = j * (this.controlsSize.width + this.margin.margin_x) + this.margin.margin_x;
tempArray[i].y = k * (this.controlsSize.height + this.margin.margin_y) + this.margin.margin_y;
k = j + 1 === this.maxWidthCount ? ++k : k;
j = j + 1 === this.maxWidthCount ? 0 : ++j;
}
// 记录数据 - 进行深拷贝
this.recordInitControlsPoisitonList = [...tempArray];
// 返回数据
return tempArray;
},
moveStart(event,index) {
// // 记录移动元素的index
this.moveId = index;
// 初始化moveToId
this.moveToId = this.moveId;
console.log(this.moveId,this.moveToId,'moveStart')
},
moveEnd(e) {
// 获取移动的差
var movePosition_x = this.endX - this.controlsArray[this.moveId].x
var movePosition_y = this.endY - this.controlsArray[this.moveId].y
console.log(movePosition_x,movePosition_y,'获取移动的差')
var line_x = parseInt(movePosition_x / 80);//移动了几列
var line_y = parseInt(movePosition_y / 80);//移动了几行
console.log(line_x,'line_x',line_y,'line_y')
this.moveToId = (this.moveId + line_x) + (line_y * 4)
console.log(this.moveId,this.moveToId,'moveEnd')
// 此处注释部分是:另一个方法:将移动前和移动后模块的位置互调,但是还没有进一步完善;可忽略
// let moveStart_x = this.controlsArray[this.moveId].x//移动前x
// let moveStart_y = this.controlsArray[this.moveId].y//移动前y
// console.log(moveStart_x,moveStart_y,'移动前')
// let moveEnd_x = this.controlsArray[this.moveToId].x//移动后x
// let moveEnd_y = this.controlsArray[this.moveToId].y//移动后y
// console.log(moveEnd_x,moveEnd_y,'移动后')
// this.controlsArray[this.moveId].x = moveEnd_x
// this.controlsArray[this.moveId].y = moveEnd_y
// this.controlsArray[this.moveToId].x = moveStart_x
// this.controlsArray[this.moveToId].y = moveStart_y
let newList = [...this.controlsArray];
// 重新排序controlsArray
console.log(this.moveId,this.moveToId,'moveEnd')
if (this.moveId == this.moveToId) {
// 如果未改变位置
this.controlsArray[this.moveId].x = moveStart_x
this.controlsArray[this.moveId].y = moveStart_y
} else {
let obj = this.controlsArray[this.moveId]//移动前的数据
console.log(obj,'obj')
newList.splice(this.moveId, 1);
newList.splice(this.moveToId, 0, obj);
}
// 将重新排序的数组归坑
this.$nextTick(function() {
setTimeout(() => {
this.controlsPositionArray = this.initControlsPosition(newList);
// 还有bug---页面的index没有更新
}, 100);
});
},
onChange: function(e) {
//最终坐标
this.endX = e.detail.x;
this.endY = e.detail.y;
},
}
}
</script>
<style lang="scss">
.sort-main{
padding: 10px;
width: 100%;
height: 100%;
.oper-imgs{
width: 98vw;
height: 98vh;//暂定
position: relative;
.item{
position: absolute;
width: 85px;
height: 85px;
border: 1px solid #ccc;
}
}
}
</style>