0👍
The problem is the draggable
‘s v-model
(i.e., numbers
) and the elements being rendered inside the draggable
(i.e., evens
) are two different data sets. When you reorder evens
by dragging its 3 items, draggable
is reordering the first 3 items in numbers
, as those items have the same indices in the two data sets.
One workaround to ensure that the list order is preserved is to render the full list of numbers
but v-show
only the even numbers:
<draggable v-model="numbers">
<template v-for="(number, index) in numbers">
<li v-show="number % 2 === 0" :key="number">{{ number }}</li>
</template>
</draggable>
Note when a rendered list can be reordered, don’t use index
as the key
, as that wouldn’t be unique between moved items, causing rendering issues (reusing an element unintentionally). I’ve used number
above, as that’s suitably unique in this case.
new Vue({
el: '#app',
components: { draggable: window.vuedraggable },
data: () => {
return {
numbers: [1, 2, 3, 4, 5, 6]
}
},
computed: {
odds() {
return this.numbers.filter(number => number % 2 === 1);
}
}
})
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.8.4/Sortable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.20.0/vuedraggable.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script>
<div id="app">
<div style="display: flex;">
<ul style="width: 50%">
<draggable v-model="numbers"
draggable="li">
<transition-group type="transition">
<template v-for="(number, index) in numbers">
<li v-show="number % 2 === 0" :key="number">{{ number }}</li>
</template>
</transition-group>
</draggable>
</ul>
<ul>
<template v-for="number in odds">
<li>{{ number }}</li>
</template>
</ul>
</div>
<pre>numbers: {{numbers}}</pre>
</div>
Source:stackexchange.com