Vue: Realize simple drag and drop function

background

It is easy to encounter the drag and drop function when doing business. Before doing it, I always thought it would be very complicated. Let’s take a look at how it is realized today.

Drag and drop API

This is a new API in HTML5. When draggable="true"setting , the element can be dragged and dropped.

<div draggable="true">
  这是拖拽元素
</div>
<div>
  这是放置区元素
</div>

Now you can drag and drop the first element.
insert image description here
Here are some common API introductions:
insert image description here
Note: The default behavior of the dragenter and dragover events is to refuse to accept any dragged and dropped elements. Therefore, we have to prevent this default behavior of the browser, usinge.preventDefault()

example

<template>
  <div>
    <transition-group
      name="drag"
      class="list"
      tag="ul"
    >
      <li
        v-for="(item, index) in todolist"
        :key="item.label"
        draggable
        :class="['list-item', { 'is-dragover': index === dragOverIndex }]"
        @dragstart="dragStart(item, index)"
        @dragover.prevent="dragOver(index)"
        @dragend="dragEnd()"
      >
        {
    
    {
    
     item.label }}
      </li>
    </transition-group>
  </div>
</template>
<script>
export default {
    
    
  data () {
    
    
    return {
    
    
      todolist: [
        {
    
     label: '列表1' },
        {
    
     label: '列表2' },
        {
    
     label: '列表3' },
        {
    
     label: '列表4' },
        {
    
     label: '列表5' },
        {
    
     label: '列表6' }
      ],
      dragStartIndex: '',
      dragStartData: '',
      dragOverIndex: ''
    }
  },
  methods: {
    
    
    dragStart (item, index) {
    
    
      this.dragStartIndex = index
      this.dragStartData = item
    },
    // 只要拖拽元素进入到放置区域就触发,这里实际是鼠标指针进入放置区域才触发
    dragOver (index) {
    
    
      this.dragOverIndex = index
    },
    dragEnd () {
    
    
      const copyTodolist = [...this.todolist]
      // 删除老的节点
      copyTodolist.splice(this.dragStartIndex, 1)
      // 在列表中目标位置增加新的节点
      copyTodolist.splice(this.dragOverIndex, 0, this.dragStartData)
      this.todolist = [...copyTodolist]
      this.dragOverIndex = ''
    }
  }
}
</script>
<style lang="scss" scoped>
.list {
    
    
  list-style: none;
  .drag-move {
    
    
    transition: transform 0.3s;
  }
  .list-item {
    
    
    position: relative;
    cursor: move;
    width: 300px;
    background: #EA6E59;
    border-radius: 4px;
    color: #FFF;
    margin: 10px 0;
    height: 50px;
    line-height: 50px;
    text-align: center;
  }
}

.list-item.is-dragover::before {
    
    
  content: "";
  position: absolute;
  bottom: -8px;
  left: 0;
  width: 100%;
  height: 4px;
  background-color: #0c6bc9;
}
.list-item.is-dragover::after {
    
    
  content: "";
  position: absolute;
  bottom: -12px;
  left: -6px;
  border: 3px solid #0c6bc9;
  border-radius: 50%;
  width: 6px;
  height: 6px;
  background-color: #fff;
}
</style>

insert image description here
Here is just a simple demonstration, there are still some problems in the specific improvement, for example:
drag 1 to the middle of 2 and 3 to become 213, so it is no problem.
But dragging 3 between 1 and 2 becomes 312, which is problematic.

Relevant information

Other drag-related open source projects
draggable
Sortable
Vue.Draggable
react-draggable

Guess you like

Origin blog.csdn.net/weixin_43972437/article/details/130871739