[Vuejs]-How to correctly reorder array when using computed properties with SortableJS and Vue?

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>

Leave a comment