因为只是做个小案例 我就直接代码写page页面里了 其实很简单 组件稍微改一下就好了
wxss
/* 设置movable-area的宽度 */
.area{
width: 100%;
}
/* a b c 每条元素的样式 */
movable-view {
width: calc(100% - 2px);
background-color: red;
height: 60rpx;
line-height: 60rpx;
color: #FFFFFF;
text-align: center;
border: royalblue 1px solid;
}
就是很普通的样式编写
js代码
Page({
data: {
//排序的集合数据源
list: [
{ text: 'a', id: 0 },
{ text: 'b', id: 1 },
{ text: 'c', id: 2 }
],
nodeHeight: 0, //记录单个节点的高度 px像素单位
//设置movable-area总高度
totalHeight: 0
},
//第一个要执行的生命周期
onLoad: function () {
//调用初始化函数
this.initialization();
},
//将指定元素 在数组中后移一个下标
moveElementBackward(arr, index) {
if((index + 1) === arr.length) {
return arr
}
const element = arr[index];
arr.splice(index, 1);
arr.splice(index + 1, 0, element);
return arr;
},
//将指定元素 在数组中前移一个下标
moveIndexForward(arr, index) {
if(index == 0){
return arr
}
var newArr = Array.from(arr);
var value1 = newArr[index];
var value2 = newArr[index - 1];
newArr[index] = value2;
newArr[index - 1] = value1;
return newArr;
},
//初始化加载数据
initialization() {
//先确认 list是有数据的 如果没有直接 return结束逻辑
let list = this.data.list
if(!list.length) {
return
}
const query = wx.createSelectorQuery()
//获取 node 第一个节点的高度 不然不知道每个节点到底多高
query.select('.node').boundingClientRect()
query.exec((doms) => {
/*
循环遍历list top是与顶部的距离
就是 当前下标乘以 当个高度
例如 一个 40 那么 第二个的位置搞好是 40 而第三个则要在 80 第一个在 0
*/
list = list.map((item,index) => {
item.top = (index*doms[0].height)
return item
})
//给总高度 单个节点高度 和 movable-area的高度赋值
this.setData({
nodeHeight: doms[0].height,
totalHeight: (doms[0].height * list.length),
list: list
})
})
},
//当用户拖拽完松开手时触发
handleTouchEnd() {
//调用initialization 初始化数据
this.initialization()
},
//当用户拖动某块元素时触发
handleTouchMove: function (event) {
//获取到当前用拖动的是第几个元素
const index = event.currentTarget.dataset.index
//定义一个list 接受tata中的list
const list = this.data.list
// 计算出 当前下标应该在的位置 加上 多 三分之二个节点的高度
const top = ((index * this.data.nodeHeight) + (this.data.nodeHeight * (2/3)))
// 计算出当前元素应该在的位置 并减去 三分之二个节点的高度
const bottom = ((index * this.data.nodeHeight) - (this.data.nodeHeight * (2/3)))
//获取movable-area和movable-view节点
const query = wx.createSelectorQuery().in(this)
query.select('.area').boundingClientRect()
query.selectAll('.node').boundingClientRect()
query.exec(res => {
//存储movable-area 元素信息
const nodeRect = res[0]
//获取用户当前拖动的元素信息
const nodeTop = res[1][index]
//用 node 与屏幕顶部的距离减去 area与屏幕顶部的距离 间距得到 node与area的距离
const distance = (nodeTop.top - nodeRect.top)
//用移动距离判断 是否下移了 2/3个节点还要多的距离
if(distance > top) {
// 调用 向后移动一个下标的函数
const newArray = this.moveElementBackward(list, index);
//调用setData 修改函数 修改 data中的 list 换成我们新处理好的函数
this.setData({
list: newArray
})
//等待 响应式数据修改并生效后再执行的nextTick
wx.nextTick(() => {
//调用初始化函数
this.initialization();
})
}
//用移动距离判断 是否上移了 2/3个节点还要多的距离
if(distance < bottom) {
//调用函数 将 当前下标上一一下 向上调1
const newArray = this.moveIndexForward(list, index);
this.setData({
list: newArray
})
//等待 响应式数据修改并生效后再执行的nextTick
wx.nextTick(() => {
//调用初始化函数
this.initialization();
})
}
})
}
});
我的注释还是写的非常认真的 大家可以好好读一读
然后 wxml 没什么特别的 就是渲染一下list文章来源:https://www.toymoban.com/news/detail-725391.html
<movable-area
class = "area"
style = "height: {{totalHeight}}px;"
>
<movable-view
wx:for="{{list}}"
wx:key="id"
data-index="{{index}}"
y="{{item.top}}"
direction="all"
class="node"
bindtouchmove="handleTouchMove"
bindtouchend="handleTouchEnd"
>
{{item.text}}
</movable-view>
</movable-area>
这样 我们就做了一个 可以上下拖动元素排序的小案例了
效果也是非常不错的文章来源地址https://www.toymoban.com/news/detail-725391.html
到了这里,关于微信小程序通过 movable-area 做一个与vuedraggable相似的上下拖动排序控件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!