Why doesn't the '@drop' event work for me in vue?
Asked Answered
F

1

29

The @drop listener doesn't work for me. It doesn't call the method I'm telling it to call.

I want to drag the chip and be able to drop it on another component, and perform a function, but at the time of dropping the chip, the dropLink method is not executed, so I assume that the @drop event is not emitted.

No errors are displayed on the console.

The rest of the events do work well, like @dragstart.

This is the code of the component I use:

<template>
  <div
    @keydown="preventKey"
    @drop="dropLink"
  >
    <template
      v-if="!article.isIndex"
    >
      <v-tooltip bottom>
        <template v-slot:activator="{ on }">
          <v-chip
            small
            draggable
            class="float-left mt-2"
            v-on="on"
            @dragstart="dragChipToLinkToAnotherElement"
          >
            <v-icon x-small>
              mdi-vector-link
            </v-icon>
          </v-chip>
        </template>
        <span>Link</span>
      </v-tooltip>

      <v-chip-group
        class="mb-n2"
        show-arrows
      >
        <v-chip
          v-for="(lk, index) in links"
          :key="index"
          small
          outlined
          :class="{'ml-auto': index === 0}"
        >
          {{ lk.text }}
        </v-chip>
      </v-chip-group>
    </template>

    <div
      :id="article.id"
      spellcheck="false"
      @mouseup="mouseUp($event, article)"
      v-html="article.con"
    />
  </div>
</template>

<script>
export default {
  name: 'ItemArticle',
  props: {
    article: {
      type: Object,
      required: true
    }
  },
  computed: {
    links () {
      return this.article.links
    }
  },
  methods: {
    mouseUp (event, article) {
      this.$emit('mouseUp', { event, article })
    },
    preventKey (keydown) {
      this.$emit('preventKey', keydown)
    },
    dragChipToLinkToAnotherElement (event) {
      event.dataTransfer.setData('text/plain', this.article.id)
    },
    dropLink (e) {
      //but this method is never called
      console.log('evento drop is ok', e)
    }
  }
}
</script>

In the project I am also using Nuxt in case that is relevant.

Fabrienne answered 23/7, 2020 at 21:22 Comment(0)
F
60

In order to make the div a drop target, the div's dragenter and dragover events must be canceled. Firefox also needs the drop event to be canceled.

You can invoke Event.preventDefault() on those events with the .prevent event modifier:

<div @drop.prevent="dropLink" @dragenter.prevent @dragover.prevent></div>

If you need to accept/reject drops based on the drag data type, set a handler that conditionally calls Event.preventDefault():

<div @drop.prevent="dropLink" @dragenter="checkDrop" @dragover="checkDrop"></div>
export default {
  methods: {
    checkDrop(e) {
      if (/* allowed data type */) {
        e.preventDefault()
      }
    },
  }
}

demo

Fondea answered 24/7, 2020 at 4:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.