mp-vue拖拽组件的实现

作为一个效率还不错的小前端,自己的任务做完之后真的好闲啊,千盼万盼终于盼来了业务的新需求,他要我多加一个排序题,然后用户通过拖拽来排序,项目经理看我是个实习生,说有点复杂做不出来就算了,我这么闲的一个人,怎么可能做不出来,慢慢磨也能磨出来好吗。

当然一开始想向大佬们学习一手,搜了半天,实现效果不佳,我以为我真的搞不出来了,可是就在我准备自己搞的时候发现了一个大佬写好了的组件,我就去npm了一手,可是报了一堆错,于是我直接去找了人家的源码hhh,研究了一手之后,开始往我的组件里套......

因为写的是小程序嘛,因此用了小程序的movable-view,人家有可以拖拽的东西直接用何必自己乱整呢,微信开发文档里面也说了movable-view只能在movable-area里面使用,当然这里面还有一些东西要配置一下,配置好了就可以实现拖动啦,于是乎按照人家的代码依葫芦画瓢结果:

<movable-area class="drag-sort" :px'}" >
      <movable-view
      v-for="(item, index) in currentList"
      :key="index"
      :x="0"
      :y="item.y"
      direction="vertical"
      disabled
      damping="40"
      :animation="item.animation"
      class="drag-sort-item"
      
      @touchstart="touchstart"
      @touchmove="touchmove"
      @touchend="touchend"
      catchtouchstart
      catchtouchmove
      catchtouchend
      :class="{'active': active == index, 'vh-1px-t': item.index > 0}">
        <view class="item">{{item.tabcontent}}</view>
      </movable-view>
    </movable-area>

在页面加载的时候拿到要拖拽的数组,然后结构一下加入其他需要的信息,比如下标(毕竟后端要这个顺序)

let arr = []
      for (const key in this.list.tabList) {
        arr.push({
          ...this.list.tabList[key],
          index: Number(key),
          y: key * this.height,
          animation: true
        })
      }
      this.currentList = arr

然后就是拖动事件balabala

/**
     * 开始拖拽的位置记录
     * @date 2019/09/18
     */
    touchstart (e) {
      // 计算y轴点击位置
      var query = wx.createSelectorQuery()
      query.select('#drag').boundingClientRect()
      query.exec((res) => {
        this.topY = res[0].top
        let touchY = e.mp.touches[0].clientY - res[0].top
        this.deviationY = touchY % this.height
        for (const key in this.currentList) {
          if ((this.currentList[key].index * this.height < touchY) && ((this.currentList[key].index + 1) * this.height > touchY)) {
            this.active = key
            this.index = this.currentList[key].index
            break
          }
        }
      })
    },
    /**
     * 触摸移动
     * @date 2019/09/18
     */
    touchmove (e) {
      if (this.active < 0) return
      let touchY = (e.mp.touches[0].clientY - this.topY) - this.deviationY
      this.currentList[this.active].y = touchY
      this.currentList[this.active].animation = false
      for (const key in this.currentList) {
        // 跳过当前操作的item
        if (this.currentList[key].index !== this.currentList[this.active].index) {
          if (this.currentList[key].index > this.currentList[this.active].index) {
            if (touchY > this.currentList[key].index * this.height - this.height / 2) {
              this.currentList[this.active].index = this.currentList[key].index
              this.currentList[key].index = this.currentList[key].index - 1
              this.currentList[key].y = this.currentList[key].index * this.height
              break
            }
          } else {
            if (touchY < this.currentList[key].index * this.height + this.height / 2) {
              this.currentList[this.active].index = this.currentList[key].index
              this.currentList[key].index = this.currentList[key].index + 1
              this.currentList[key].y = this.currentList[key].index * this.height
              break
            }
          }
        }
      }
    },
    /**
     * 拖拽事件结束传递参数信息给父组件
     * @date 2019/09/18
     */
    touchend (e) {
      if ((this.index !== this.currentList[this.active].index) && (this.active > -1)) {
        this.$emit('change', {
          // 拖拽结束后的内容
          updateList: this.currentList
        })
      }
      this.currentList[this.active].animation = true
      this.currentList[this.active].y = this.currentList[this.active].index * this.height
      this.active = -1
    }

一个可拖拽的组件就写好了,要什么信息再自己后期加就是了hhh