SortableJS / Vue.Draggable

Vue drag-and-drop component based on Sortable.js
https://sortablejs.github.io/Vue.Draggable/
MIT License
20.03k stars 2.89k forks source link

force-fallback prop not propagated to sortablejs if updated? #934

Open saraha33 opened 3 years ago

saraha33 commented 3 years ago

Dear VueDraggable people,

Description of the problem

my problem is the following:

im using vuedraggable in a component that should be able to be server-side rendered - therefore i only set the sortable.js option force-fallback in the mounted hook:

the component:

  <draggable
    v-model="list"
    :sort="false"
    :disabled="isMobile || selectActive"
    :group="{ name: dragName, pull: 'clone', put: false }"
    :set-data="modifyDragItem"
    :force-fallback="!dragAndDropCapable"
    tag="ul"
    class="base-menu-list"
    @start="dragStart"
    @end="dragEnd">
    <li
      v-for="(item, index) in list"
      :key="item.id || item.title"
      class="base-menu-list__list-entry">
      <!-- ..... -->
    </li>
  </draggable>

the relevant script part:

import Draggable from 'vuedraggable';
export default {
  name: 'BaseMenuList',
  components: {
    Draggable,
  },
  data() {
    return {
      dragAndDropCapable: false, // which makes force-fallback: true!
    };
  },
  mounted() {
    // now the variable is becoming true if browser supports drag and drop and force-fallback --> false
    this.dragAndDropCapable = ('DragEvent' in window);
  },
};

when i check in the vue developer tools i can see that the prop is correctly saying force-fallback: false:

vuedraggable $attrs

however how i noticed that this might not be propagated to sortablejs is that the 'sortable-fallback' class is actually added to to class attribute on drag start: sortable-fallback

this unfortunately causes that my set-data function setDragItem() is not triggered and the drag image is not set correctly...

if i revert the code to have a computed property:

export default {
  .....
    computed: {
      dragAndDropCapable() {
        return ('DragEvent' in window);
      },
  },
  ....
}

everything works correctly. (however this would not work with SSR)

So is there any wrongdoing on my side? Anything i could do differently to achieve that force-fallback is set to false correctly? Or is it really only possible to set the option on render atm? If so - is that the intended behavior our could it be considered a bug?

CodeSandbox link

I also created a code sandbox with the code outlined above to demonstrate the problem: https://codesandbox.io/s/vuedraggable-fg4tp?file=/src/components/Draggable.vue

PS: found out now that apparently it is the nativeDraggable variable of sortablejs that is not updated after creation of the Sortable instance (everything works again if i do this in mounted this.$refs.draggable._sortable.nativeDraggable = true;)

jacekkarczmarczyk commented 3 years ago

works with :options="{ forceFallback: ...}" but gives a warning Options props is deprecated, add sortable options directly as vue.draggable item, or use v-bind