SortableJS / vue.draggable.next

Vue 3 compatible drag-and-drop component based on Sortable.js
https://sortablejs.github.io/vue.draggable.next/#/simple
MIT License
3.91k stars 531 forks source link

Not working with webpack/laravel mix and build for production #194

Closed kskrlinnorth2 closed 1 year ago

kskrlinnorth2 commented 1 year ago

It works with npm run dev, but it doesn't work with npm run prod. This (laravel-mix) is wrapper for webpack (v5.60.0)

Using Vue 3.2.41, vuedraggable 4.1.0 and laravel-mix 6.0.49

Step by step scenario

When running npm run dev it works, but using npm run prod it doesn't work.

npm scripts:

"dev": "mix"
"prod": "mix --production"

Webpack:

const mix = require("laravel-mix");

mix.js("resources/js/app.js", "public/js")
  .vue()
  // ...some postCss and other rules (not important)
  .purgeCss({safelist: {greedy: [/^sortable/]}}) // No help from this
  .sourceMaps(false, "source-map")
  .extract();

if (mix.inProduction()) {
  mix.version().disableNotifications();
}

Code implementation:

<script setup>
import draggable from "vuedraggable";

const props = defineProps({
  items: Array, // Array of objects [{id: 1, name: "item-1"}, {id: 2, name: "item-2"}]
});

const reorderItems = () => {
  props.items.forEach((item) => console.log(item.id, item.name));
};
</script>

<template>
<draggable
  v-model="items"
  group="items"
  @change="reorderItems"
  handle=".drag"
  item-key="id"
  tag="ul">
    <template #item="{ element }">
      <li>
        <span class="drag">Drag</span>
        <span>{{ element.name }} | {{ element.id }}</span>
      </li>
    </template>
</draggable>
</template>

Actual Solution

I can drag item and they reorder visually, but on drop they just reset to starting state and they are not reordered (change event also returns old array, not reordered).

Expected Solution

I expect it to work same as on dev build. Plugin is using classes starting with sortable- so I tried to whitelist them (that usually worked for plugins), but no luck.

kskrlinnorth2 commented 1 year ago

It works if I extract v-model variable to reference, which is weird, because Vue should warn be about it (and it is also much weirder why it works on dev, but not on prod build):

let sortableItems = ref(props.items);

<draggable v-model="sortableItems"></draggable>