Почему Vue-Draggable ведет себя странно, если добавить больше элементов?

Сделал пример на Codepen.
А теперь проблема: если в сторе раскомментировать остальные элементы, то Draggable начинает вести себя мягко говоря странно (сортирует элементы каким-то случайным способом).
Что можно с этим сделать, и почему он так себя ведёт?

<div id="app">
  <draggable v-model="myList">
    <div class="items" v-for="item in myList" :key="item.id">{{item.title}}</div>
  </draggable>
</div>


const mapState = Vuex.mapState;
const mapMutations = Vuex.mapMutations;
const mapGetters = Vuex.mapGetters;

function dynamicSort(property) {
    var sortOrder = 1;

    if (property[0] === "-") {
        sortOrder = -1;
        property = property.substr(1);
    }

    return function (a, b) {
        if (sortOrder == -1) {
            return b[property].toString().localeCompare(a[property]);
        } else {
            return a[property].toString().localeCompare(b[property]);
        }
    }
}

const store = new Vuex.Store({
  state: {
    itemsList: [
      {id: 1, sort: 0, title: 'title 1', column: 1},
      {id: 2, sort: 0, title: 'title 2', column: 1},
      {id: 3, sort: 0, title: 'title 3', column: 2},
      {id: 4, sort: 0, title: 'title 4', column: 2},
      {id: 5, sort: 0, title: 'title 5', column: 1},
      {id: 6, sort: 0, title: 'title 6', column: 2},
      {id: 7, sort: 0, title: 'title 7', column: 1},
      {id: 8, sort: 0, title: 'title 8', column: 1},
      {id: 9, sort: 0, title: 'title 9', column: 1},
      // {id: 10, sort: 0, title: 'title 10', column: 1},
      // {id: 11, sort: 0, title: 'title 11', column: 1},
      // {id: 12, sort: 0, title: 'title 12', column: 1},
      // {id: 13, sort: 0, title: 'title 13', column: 1},
      // {id: 14, sort: 0, title: 'title 14', column: 1},
      // {id: 15, sort: 0, title: 'title 15', column: 1},
    ]
  },
  getters: {
    filteredItems: state => {
      let items = state.itemsList.filter(item => item.column === 1);
      return items.sort(dynamicSort("sort"));
    }
  },
  mutations: {
    saveSort (state, items) {
      items.forEach((el, idx) => {
        const storeItem = store.state.itemsList.find(item => item.id === el.id);
        storeItem.sort = idx;
      });
    }
  }
});

var app = new Vue({
  store,
  el: '#app',
  computed: {
    ...mapGetters(["filteredItems"]),
    myList: {
        get() {
            return this.filteredItems
        },
        set(items) {
            this.saveSort(items)
        }
    }
  },
  methods: {
    ...mapMutations(["saveSort"])
  }
})
  • Вопрос задан
  • 375 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега Vue.js
Числа как строки сравниваете. Так что да, '2' > '10', всё правильно.

Что делать? Ну, очевидно - сравнивайте числа как числа. Придётся усложнить метод сортировки, чтобы он умел понимать, с каким типом данных работает. Или, если лень переделывать, можно по-быстрому закостылить: числа сразу превращать в строки, результат сравнения которых будет таким же, как у чисел - дополните их нулями спереди.

UPD. Массив items, передаваемый в мутацию saveSort, содержит те же объекты, что и массив itemsList из стейта, так что никакого find здесь не надо:

mutations: {
  saveSort: (state, items) => items.forEach((n, i) => n.sort = i),
},
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы