Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

115
Vistas
Vue3 For-Loop with Computed Property triggers onDragEnd immediately

I am trying do develop my own simple drag and drop functionality for a form builder. I have got a list of items which is rendered in a v-for loop with a computed property. On onDragStart I set the state isDragging. This should alter the list in the computed property and insert some slots where I can drop the dragged item. But immediatly after dragging an item, it triggers the onDragEnd Event.

Initialy i was missing the :key property, but adding it didnt solve the problem. Hopefully someone knows a solution or has an idea whats wrong.

Here is a Link to the code: https://jsfiddle.net/elrihor/vwb3k6qc/49/

Vue.createApp({
  data() {
    return {
      list: [{
          id: 'i1',
          name: 'Apfel',
        },
        {
          id: 'i2',
          name: 'Banane',
        },
        {
          id: 'i3',
          name: 'Kirsche',
        },
        {
          id: 'i4',
          name: 'Orange',
        },
      ],
      props: {
        item: {
          props: {
            draggable: true,
            ondragstart: ($event) => {
              this.startDrag();
            },
            ondragend: ($event) => {
              this.endDrag();
            },
          },
        },
        slot: {
          props: {
            ondrop: ($event) => {
                $event.preventDefault();
              this.onDrop($event);
            },
            ondragover: ($event) => {
                $event.preventDefault();
            }
          },
        },
      },
      isDragging: false
    }
  },
  computed: {
    dragList() {
      let dragList = this.list;

      if (this.isDragging) {
        dragList = dragList.reduce((r, a) => r.concat(a, {
          type: 'slot',
          name: 'Slot'
        }), [{
          type: 'slot',
          name: 'Slot'
        }]);
      }

      dragList = dragList.map((item, index) => {
        return {
          ...item,
          id: !item.id ? 's' + index : item.id,
          type: item.type == 'slot' ? 'slot' : 'item',
        };
      });

      return dragList;
    }
  },
  methods: {
    getProps(type) {
      return this.props[type].props;
    },
    startDrag() {
      console.log('start');
      this.isDragging = true;
    },
    endDrag() {
      console.log('end');
      this.isDragging = false;
    },
    onDrop(e) {
      console.log('drop');
    }
  }
}).mount('#app')
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

I think the issue lies in choosing to use the ondragstart event. When this is fired, the DOM is re-rendered to display your slots, which moves things around so that your mouse cursor is no longer over the element itself. dragend is then fired before the drag actually commenced. Change this simply to ondrag and it will work:

https://jsfiddle.net/m7ps3f40/

To debug and figure this out, I simplified your fiddle a lot. I felt the dragList computed and the :bind="getProps" used more code and is less readable than the a simpler approach of just using HTML elements and Vue-style events for dragging. You might find it interesting to take a look:

https://jsfiddle.net/o5pyhtd3/2/

but of course your fiddle might be a cut down version of a bigger piece of code, so perhaps you need to stick to your approach.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda