js 拖拽排序

59 阅读1分钟

js 拖拽排序

<template>
  <div class="box">
    <div class="drag-box" @dragstart="onDragstart" @dragover="onDragover" @dragenter="onDragenter" @dragend="onDragend">
      <div class="item" draggable="true" v-for="item in list" :key="item.id">{{ item.name }}</div>
    </div>
  </div>
</template>

<script>
import {nanoid} from 'nanoid'
export default {
  data () {
    return {
      // 可拖动的容器元素
      container: null,
      // 拖动的目标元素
      soucreNode: null,
      list: [
        {
          id: nanoid(),
          name: 1,
        },
        {
          id: nanoid(),
          name: 2,
        },
        {
          id: nanoid(),
          name: 3,
        },
        {
          id: nanoid(),
          name: 4,
        },
        {
          id: nanoid(),
          name: 5,
        },
        {
          id: nanoid(),
          name: 6,
        },
      ]
    }
  },
  mounted() {
    this.container = document.querySelector('.drag-box')
  },
  methods: {
    onDragend(e) {
      this.soucreNode.classList.remove('moveing')
    },
    onDragover(e) {
      e.preventDefault();
    },
    onDragstart(e) {
        // 防止拖拽时拖拽的样式公用
      setTimeout(() => {
        e.target.classList.add('moveing')
      }, 0)
      this.soucreNode = e.target
    },
    onDragenter(e) {
      e.preventDefault();
      // e是当前进入的元素 如果是当前元素或者是父元素 什么也不做
      // console.log(e.target === this.container || e.target === this.soucreNode)
      if (e.target === this.container || e.target === this.soucreNode) {
        return
      }

      const children = [...this.container.children]

      const sourceIndex = children.indexOf(this.soucreNode)

      const targetIndex = children.indexOf(e.target)

      if (sourceIndex < targetIndex) {
        // 往下拖拽 拖拽进入的当前节点的下一个节点前方插入
        this.container.insertBefore(this.soucreNode, e.target.nextElementSibling)
      } else {
        // 往上拖拽 拖拽进入的当前节点的前方插入
        this.container.insertBefore(this.soucreNode, e.target)
      }

      const temp = this.list[sourceIndex]

      const targetData = this.list[targetIndex]
        
      // 对数组进行排序
      this.list[sourceIndex] = targetData
      this.list[targetIndex] = temp

    }
  }
}
</script>

<style>
.drag-box {
  height: 600px;
  border: 1px solid  #eee;
  padding: 20px;
}
.item {
  height: 30px;
  border-radius: 4px;
  background: skyblue;
  cursor: pointer;
  text-align: center;
  border: 1px solid skyblue;
  margin: 10px 0;
}
.item.moveing {
  background: transparent;
  border: 1px dashed #ccc;
  color: transparent;
}
</style>