用movable组件写出简短的拖放/拖拽/拖动 排序,含详细的讲解【拎包哥】
发布于 4 年前 作者 mhou 4286 次浏览 来自 分享

「前言」

这应该是社区目前(2020/12/8)最简短的拖拽排序教程之一,助你快速上手哦。

拖放排序是前端中可以和订单规格选择等等比较的,知识点最密集的基础之一。

如果你有html的基础知识,你会发现微信小程序其实是集成度非常高的框架,和vue,react等响应式前端框架没有本质的区别,甚至集成度还更高。

所以在这里好好利用小程序自身的组件及其属性,就能快速写出简短的拖拽排序。

========================效果图=============================

微信小程序

========================HTML篇=============================

  • 只使用小程序提供的movable组件即可。它简化了拖放排序的条件 ,让我们只需要控制y值就可以确定组件的位置。
  • 拖放中的放动作有手指离开的动作,而movable组件没有这个属性,所以引用了touchend。

<movable-area class=‘ctr’>> <block wx:for=’{{arr}}’ wx:key=‘x’>> <movable-view bindchange=‘change’ bindtouchend=‘end’ y=’{{item.y}}’ class=‘item’ direction=‘vertical’>> {{item.name}}> </movable-view>> </block>> </movable-area>

(ps. 由于微信社区难以理解的bug,这里的代码不能放在代码片段里)

========================CSS篇=============================

  • 在这个CSS我只有item的height用到了px,因为y值的像素单位是px。
  • 在css尽量不要增加额外的height属性,否则这个组件就不精准了。
.ctr{
  width400rpx;
  height800rpx;
  border1rpx solid black;
}
.item{
  width400rpx;
  height50px;
  /* 与后来确定y值的的 i * 50对应 */
  border-bottom1rpx solid black;
  box-sizing: border-box;
  /* 让边框内嵌,否则会随着1rpx的叠加而让y值变得不精准 */
}

=========================JS篇==============================

主要步骤

  1. 用y值来确定拖放动作中放的位置
  2. 互换排序双方的下标(这也是排序的本质)

注意

  • 拖拽的数组arr一开始就放在onLoad方法而不是data里,否则会因为data的提前渲染而产生缓慢的位移。
  • movable-view一开始是重叠的,所以要根据下标来确定每个item的y值。
  • bindchange对应的是拖行为,我们只需要在这个方法里获取我们在拖行为时产生的y值。

那么在touchend的时候就可以获得bindchange最后一个y值,并借此确定放行为的对应的下标。

Page({
  onLoad() {  // 注意数组放onLoad里,不过你也可以放在data里,体会不良的后果。
    var arr = [
      {name: 'Mike'},
      {name: 'Paul'},
      {name: 'Peter'},
      {name: 'Andy'},
      {name: 'Larry'}
    ]
    for (var i in arr) {
      arr[i].y = i * 50
    }
    // 让数组每个下标都获得对应的y值
    this.setData({
      arr
    })
  },
  change(e) {
    this.y = e.detail.y
  },
  end(e) {
    var arr = this.data.arr
    var id = e.currentTarget.id
    var currentId = this.y / 50
    // 用touchend捕获手指离开后的y值,并除以50,反推触摸离开后对应的当前的item的id。
    if (id < currentId) {
      var transferId = Math.ceil(currentId)
    } else {
      var transferId = Math.floor(currentId)
    }
    // 根据初始id和离开屏幕时的id判断自己要交换的下标+1还是-1。
    var save = arr[id]
    arr[id] = arr[transferId]
    arr[transferId] = save
    for (var i in arr) {
      arr[i].y = i * 50
    }
    // 重新计算数组每个下标对应的y值。
    this.setData({
      arr
    })
  }
})

------------------------------------------进阶篇vue-cli-------------------------------------------

vue-cli4

========================HTML篇=============================

挖坑,在研究vue脚手架vue-cli4的拖拽排序,未完待续。

1 回复

有问题或改进建议请留言哦。

回到顶部