Как правильно изменить порядок массива при использовании вычисляемых свойств с SortableJS и Vue?

У меня есть array элементов, но я хочу отобразить их и предоставить функцию Draggable (SortableJS), но только часть этого array.

Для этого я использовал вычисляемое свойство из исходного массива данных и разделил массив на два массива, я использовал эти вычисляемые массивы для создания списка, но когда я перетаскиваю и пытаюсь изменить порядок перетаскивания списка, кажется, что что-то не так с индексы, как в примере ниже, если вы попытаетесь перетащить первый список, он не изменит порядок, а второй.

Итак, как я могу решить эту проблему?

new Vue({
  el: '#app',
  components: { draggable: window.vuedraggable },
  data: () => {
    return {
      numbers: [1, 2, 3, 4, 5, 6]
    }
  },
  computed: {
    evens() {
      return this.numbers.filter(number => number % 2 === 0);
    },
    odds() {
      return this.numbers.filter(number => number % 2 === 1);
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/[email protected]/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 evens">
            <li :key="index">{{ number }}</li>
          </template>
        </transition-group>
      </draggable>
    </ul>

    <ul>
      <template v-for="number in odds">
        <li>{{ number }}</li>
      </template>
    </ul>
  </div>
</div>


person João Hamerski    schedule 06.03.2021    source источник


Ответы (1)


Проблема заключается в том, что draggable представляет собой v-model (т. е. numbers), а элементы, визуализируемые внутри draggable (т. е. evens), представляют собой два разных набора данных. Когда вы переупорядочиваете evens, перетаскивая его 3 элемента, draggable переупорядочивает первые 3 элемента в numbers, так как эти элементы имеют одинаковые индексы в двух наборах данных.

Одним из обходных путей для обеспечения сохранения порядка списка является отображение полного списка numbers, но v-show только четные числа:

<draggable v-model="numbers">
  <template v-for="(number, index) in numbers">
    <li v-show="number % 2 === 0" :key="number">{{ number }}</li>
  </template>
</draggable>

Обратите внимание, что когда отображаемый список может быть переупорядочен, не используйте index вместо key, так как это не будет уникальным для перемещенных элементов, вызывая проблемы с отображением (непреднамеренное повторное использование элемента). Я использовал number выше, так как в данном случае он достаточно уникален.

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/[email protected]/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>

person tony19    schedule 07.03.2021
comment
Так что в принципе нет хорошего способа сделать то, что я пытаюсь сделать? Только имея два разных массива? Поскольку смысл заключался в том, чтобы использовать два вычисляемых массива и переупорядочивать их в правильном порядке, когда я использую перетаскивание каждого из двух списков массивов вычисляемых массивов, я просто не стал вставлять код, потому что думал, что это не имеет значения. - person João Hamerski; 07.03.2021