Recently I am learning Vue, making a small demo while learning. There is a small function to use drag and drop, by the way also learn to drag and drop. Drag and drop is an HTML5 standard that is easy to implement on normal pages for tutorials, but vUE is mostly data-driven and DOM manipulation is not recommended.

Built-in HTML drag and drop API

The HTML drag and drop API is a built-in method that contains several events and attributes, but can be reduced to two types of element thinking.

  • Draggable element: An element that can be dragged
  • Deployable element: An element that can accept the dragged element

This makes it much easier to analyze drag-and-drop events.

Drag and drop event

There are eight drag-and-drop events in the API that we can use in our program.

  • Drag: A dragable item is dragged
  • Dragstart: Starts dragging dragable elements
  • Dragend: to end a drag (such as releasing the mouse)
  • Dragenter: Drags an item into a placable element
  • Dragleave – Dragable item leaves the placing element
  • Dragover: a dragable item moved on a placable element (called every 100 milliseconds or so)
  • Drop: A draggable item is placed on a deployable element

The dataTransfer object

One of the most important things about the drag-and-drop API is that it adds a dataTransfer object to the event.

The dataTransfer object allows us to set the data when we start dragging the element and access the same data when we drop the element in the drag-and-drop area. We should know a few things about dataTransfer properties and methods (see the dataTransfer API documentation for more information).

  • DropEffect: current drag-and-drop operations (for example, move, copy)
  • Effectalhoward: Specify drag and drop operations
  • SetData (name, val) : allows us to add values to the dataTransfer object
  • GetData (name) : Retrieves the stored value

Create your own drag-and-drop system

As you can see in the example, there are two lists between which we can smoothly drag and drop items.

Configure our project

First, we must set up the data. In the script, create an array of item objects with the following attributes:

  • Id: A unique ID so that we can look up objects
  • Title: To display text
  • List: The list to which it belongs.

Add three items to this array:

data () {
    return {
      items: [{id: 0.title: 'Item A'.list: 1
      },
      {
        id: 1.title: 'Item B'.list: 1
      },
      {
        id: 2.title: 'Item C'.list: 2}}}]Copy the code

Two computed properties are also created to filter the list of items into items in Listing 1 and items in Listing 2.

computed: {
    listOne () {
      return this.items.filter(item= > item.list === 1)
    },
    listTwo () {
      return this.items.filter(item= > item.list === 2)}}Copy the code

Template code to create

This is the outline of the component. The code displays everything, but there is no drag-and-drop capability.

<template>
  <div>
    <div class='drop-zone'>
      <div v-for='item in listOne' :key='item.title' class='drag-el'>
        {{ item.title }}
      </div>
    </div>
    <div class='drop-zone'>
      <div v-for='item in listTwo' :key='item.title' class='drag-el'>
        {{ item.title }}
      </div>
    </div>
  </div>
</template>
Copy the code

The style of the component is not important. It’s important that your placement area has a certain height, even if there are no internal elements, otherwise you can’t hover over it!

<style scoped>
  .drop-zone {
    background-color: #eee;
    margin-bottom: 10px;
    padding: 10px;
  }
 
  .drag-el {
    background-color: #fff;
    margin-bottom: 10px;
    padding: 5px;
  }
</style>
Copy the code

Do this by adding some padding to the drag-and-drop area style.

Add drag and drop

Start by adding some methods to your script: one to use when you start dragging elements and another to use when you drop elements.

For the startDrag method, we want to use the dataTransfer property discussed earlier to store the ID of the element to be dragged. And the drag event will be an action.

startDrag: (evt, item) = > {
      evt.dataTransfer.dropEffect = 'move'
      evt.dataTransfer.effectAllowed = 'move'
      evt.dataTransfer.setData('itemID', item.id)
}
Copy the code

We then retrieve the stored ID in onDrop so that we can access the correct items in the array.

onDrop (evt, list) {
      const itemID = evt.dataTransfer.getData('itemID')
      const item = this.items.find(item= > item.id == itemID)
      item.list = list
}
Copy the code

Add the template code. You start by adding events to events. You need to make the element dragable and detect the drag start event.

<div
        class='drag-el'
        v-for='item in listTwo'
        :key='item.title'
        draggable
        @dragstart='startDrag($event, item)'
 >
        {{ item.title }}
</div>
Copy the code

Because of the draggable attribute, if you run the program, you should be able to drag elements like this, but you can’t drag them anywhere.

Let’s give it a drop area that accepts draggable elements. Start by adding a DROP event listener that calls the onDrop method.

<div
      class='drop-zone'
      @drop='onDrop($event, 1)'
>
Copy the code

But note that we must call preventDefault on dragEnter and dragOver.

By default, these methods do not allow you to delete elements. So in order for our DROP event to work properly, its default action must be prevented.

You can do this using Vue’s built-in.Prevent event modifier.

<div
      class='drop-zone'
      @drop='onDrop($event, 1)'
      @dragover.prevent
      @dragenter.prevent
>
Copy the code

Now run the program and you can see that everything is fine. We can drag and drop elements between two different lists.

Finally, ask for a like or give 🌟🌟