分享一个基于vue2.0+的拖动排序组件

先来个效果图:
在这里插入图片描述

组件的实现是基于改变源数据的数组位置,所以使用的话必须要对传进去的源数据做一次深拷贝,操作完成后再传排序后的数组回去;
事件是采用了drag系列事件,跟需求和用户操作习惯比较吻合;
图标是element-ui里面的;
过度效果是vue的transition-group标签实现的,这里要注意的是transition-group包裹的次级元素一定要有唯一的key,而且依旧要设置transition样式,否则不会有过度效果;
获取数组下标的处理方式不是特别好,希望路过的大神帮忙指点一下,蟹蟹;

下面是源码:

<template>
  <ul class="dragSort">
    <transition-group>
      <li
        draggable="true"
        @dragstart="handlerDragstart"
        @drag="handlerDrag"
        @dragend="handlerDragend"
        :id="index"
        v-for="(item, index) in dataList"
        :key="item.a">
        【{{index+1}}】{{item.a}}
        <i class="el-icon-sort"/>
      </li>
    </transition-group>
  </ul>
</template>
<script>
export default {
  props: {
  },
  name: 'dragSort',
  data () {
    return {
      dataList: [
        { a: '测试类目-001' },
        { a: '测试类目-002' },
        { a: '测试类目-003' },
        { a: '测试类目-004' },
        { a: '测试类目-005' },
        { a: '测试类目-006' },
        { a: '测试类目-007' }
      ]
    }
  },
  methods: {
    handlerDragstart (e) {
      const { y, target } = e
      target.style.opacity = '.5'
      target.oriY = y
      target.oriIndex = Number(target.id)
    },
    handlerDrag (e) {
      const { y, target } = e
      if (y === 0) return
      const offset = y - target.oriY
      const length = this.dataList.length
      if (Math.abs(offset) > target.offsetHeight) {
        const index = target.oriIndex
        const copyList = [...this.dataList]
        let targetIndex = index + Math.round(offset / target.offsetHeight)
        if (targetIndex > length - 1) {
          targetIndex = length - 1
        } else if (targetIndex < 0) {
          targetIndex = 0
        }
        const readyToAppend = copyList.splice(index, 1)[0]
        copyList.splice(targetIndex, 0, readyToAppend)
        target.oriIndex = targetIndex
        target.oriY = y
        this.dataList = copyList
      }
    },
    handlerDragend (e) {
      const { y, target } = e
      target.style.opacity = '1'
    }
  }
}
</script>
<style scoped lang="scss">
.dragSort{
  width: 200px;
  list-style: none;
  margin: 0;
  padding: 0;
  li{
    text-align: left;
    border: 1px solid #f1f1f1;
    padding: 10px;
    box-shadow: 0 2px 8px 0 rgba(0, 0, 0, .1);
    border-radius: 5px;
    margin-bottom: 10px;
    cursor: move;
    width: 100%;
    background: #fff;
    transition: all .3s;
    z-index: 1;
    i {
      font-size: 16px;
      color: #409EFF;
      float: right;
    }
  }
}
</style>

转载请注明出处蟹蟹

猜你喜欢

转载自blog.csdn.net/qq_19694913/article/details/84570997